1. Why does my Exercism task fail?
- Posted by axtens_bruce Feb 13, 2023
- 734 views
Code
public function square(integer n if n < 1 or n > 64 then return "square must be between 1 and 64" end if return power(2, (n-1)) end function public function total() atom sum = 0 for i = 1 to 64 do sum += square(i) end for return sum end function
Tests
include std/unittest.e include grains.ex test_equal("grains on square 1",square(1),1) test_equal("grains on square 2",square(2),2) test_equal("grains on square 3",square(3),4) test_equal("grains on square 4",square(4),8) test_equal("grains on square 16",square(16),32768) test_equal("grains on square 32",square(32),2147483648) test_equal("grains on square 64",square(64),9223372036854775808) test_equal("square 0 raises an exception",square(0),"square must be between 1 and 64") test_equal("negative square raises an exception",square(-1),"square must be between 1 and 64") test_equal("square greater than 64 raises an exception",square(65),"square must be between 1 and 64") test_equal("returns the total number of grains on the board", total(), 18446744073709551615) test_report()
Run, failing on test test_equal("grains on square 64",square(64),9223372036854775808)
>eutest interpreting t_grains.e: failed: grains on square 64, expected: 9.22337203685478e+018 but got: -9.22337203685478e+018 11 tests run, 10 passed, 1 failed, 91% success FAILURE: t_grains.e program died with status 1 Test results summary: FAIL: t_grains.e Files (run: 1) (failed: 1) (0% success)
2. Re: Why does my Exercism task fail?
- Posted by jimcbrown (admin) Feb 13, 2023
- 680 views
Code
public function square(integer n if n < 1 or n > 64 then return "square must be between 1 and 64" end if return power(2, (n-1)) end function public function total() atom sum = 0 for i = 1 to 64 do sum += square(i) end for return sum end function
Tests
include std/unittest.e include grains.ex test_equal("grains on square 1",square(1),1) test_equal("grains on square 2",square(2),2) test_equal("grains on square 3",square(3),4) test_equal("grains on square 4",square(4),8) test_equal("grains on square 16",square(16),32768) test_equal("grains on square 32",square(32),2147483648) test_equal("grains on square 64",square(64),9223372036854775808) test_equal("square 0 raises an exception",square(0),"square must be between 1 and 64") test_equal("negative square raises an exception",square(-1),"square must be between 1 and 64") test_equal("square greater than 64 raises an exception",square(65),"square must be between 1 and 64") test_equal("returns the total number of grains on the board", total(), 18446744073709551615) test_report()
Run, failing on test test_equal("grains on square 64",square(64),9223372036854775808)
>eutest interpreting t_grains.e: failed: grains on square 64, expected: 9.22337203685478e+018 but got: -9.22337203685478e+018 11 tests run, 10 passed, 1 failed, 91% success FAILURE: t_grains.e program died with status 1 Test results summary: FAIL: t_grains.e Files (run: 1) (failed: 1) (0% success)
What does running "eui version" return for you?
This is really odd. You have the expected and outcome backwards (see https://openeuphoria.org/docs/std_unittest.html#_6306_unittestingframework ) so square(64) works correctly (more proof - if square(64) returned the wrong value, total() would also be wrong), but it seems using the hardcoded literal fails as it is somehow incorrectly interpreted to be a negative value.
Also, what happens if you specify 9.223372037e+18 as the result instead of 9223372036854775808 ?
3. Re: Why does my Exercism task fail?
- Posted by axtens_bruce Feb 13, 2023
- 665 views
What does running "eui version" return for you?
>eui -v Euphoria Interpreter v4.1.0 development 64-bit Windows, Using System Memory Revision Date: 2015-02-02 14:18:53, Id: 6300:57179171dbed
You have the expected and outcome backwards (see https://openeuphoria.org/docs/std_unittest.html#_6306_unittestingframework )
Reversing it makes no difference though.
Also, what happens if you specify 9.223372037e+18 as the result instead of 9223372036854775808 ?
test_equal("grains on square 64",square(64),9.223372037e+18) test_equal("grains on square 64",9.223372037e+18,square(64))
interpreting t_grains.e: failed: grains on square 64, expected: 9.22337203685478e+018 but got: 9.223372037e+018 failed: grains on square 64, expected: 9.223372037e+018 but got: 9.22337203685478e+018
test_equal("grains on square 64",square(64),9.22337203685478e+018) test_equal("grains on square 64",9.22337203685478e+018,square(64))
interpreting t_grains.e: failed: grains on square 64, expected: 9.22337203685478e+018 but got: 9.22337203685478e+018 failed: grains on square 64, expected: 9.22337203685478e+018 but got: 9.22337203685478e+018Curiouser and curiouser.
-Bruce
4. Re: Why does my Exercism task fail?
- Posted by petelomax Feb 13, 2023
- 706 views
First thing I'd do is subtract and print the difference of the offending numbers.
On Phix, 32-bit is 2048 out, which (I know you're not using and) is about right since there are only 53 bits of precision, which
makes it pretty much unavoidable when using *10 rather than *2 to construct it, whereas on 64-bit Phix it sails through.
One thing I did fix about 5 months ago was an error in the (Phix) parser:
Bugfix: constant n = 9_007_199_254_740_991 was creating the wrong constant, ending in 92 not 91. The tokeniser was performing TokN = TokN*10 + Ch-'0', but the (TokN*10 + Ch) part was exceeding available precision (temporarily), which no longer happens with the corrected TokN = TokN*10 + (Ch-'0').
(as worded that is strictly speaking a 32-bit error, but no doubt there was a similar 64-bit one)
One quick and dirty fix might be to replace your 9223372036854775808 with power(2,63), works for me and even on 32-bit Phix anyway.
For absolute correctness you might want to be testing "res=9223372036854775808 or res=power(2,63)"