diff --git a/lib/soml/parfait/integer.soml b/lib/soml/parfait/integer.soml index ea010f8a..56bb8265 100644 --- a/lib/soml/parfait/integer.soml +++ b/lib/soml/parfait/integer.soml @@ -8,85 +8,24 @@ class Integer < Value end end - int high_times( int by_high , int by_low) - int num_high = self >> 16 - int num_low = self & 65535 - - int res_high = by_high * num_high - - num_low = by_high * num_low - num_high = num_high * by_low - - num_high = num_low + num_high - - num_high = num_high >> 16 - - res_high = res_high + num_high - - return res_high - - end - - int low_times( int by_high , int by_low) - - int num_high = self >> 16 - int num_low = self & 65535 - - int res_low = by_low * num_low - - num_low = by_high * num_low - num_high = num_high * by_low - - num_low = num_low + num_high - - num_low = num_low << 16 - - res_low = res_low + num_low - - return res_low - - end - - int div10() - int minus_10 = self - 10 - int me = self - - int tmp = me >> 2 - me = me - tmp - - tmp = me >> 4 - me = me + tmp - - tmp = me >> 8 - me = me + tmp - - tmp = me >> 16 - me = me + tmp - me = me >> 3 - - int tmp2 = me << 2 - tmp2 = me + tmp2 - - tmp2 = tmp2 << 1 - - if_minus(tmp2 - minus_10) - me = me + 1 - end - return me - end - - int div10_almost() - int me = self - if_zero( me >> 26 ) - me = me + 1 - end - int res_high = me.high_times( 26214 , 26215 ) - int res_low = self >> 31 - res_high = res_high >> 2 - - return res_high + res_low + int div10_soml() + int tmp = self >> 1 + int q = self >> 2 + q = q + tmp + tmp = q >> 4 + q = q + tmp + tmp = q >> 8 + q = q + tmp + tmp = q >> 16 + q = q + tmp + q = q >> 3 + int r = q * 10 + r = self - r + r = r + 6 + r = r >> 4 + return q + r end Word as_string(Word str) diff --git a/test/soml/helper.rb b/test/soml/helper.rb index ac2165ad..69c15a36 100644 --- a/test/soml/helper.rb +++ b/test/soml/helper.rb @@ -28,9 +28,13 @@ module RuntimeTests end def check ret = nil - load_program + i = check_local check_remote ret - exit + i + end + + def check_local ret = nil + load_program interpreter = Register::Interpreter.new interpreter.start @machine.init count = 0 @@ -44,7 +48,6 @@ module RuntimeTests assert_equal Parfait::Message , interpreter.get_register(:r0).class assert_equal ret , interpreter.get_register(:r0).return_value , "exit wrong #{@string_input}" end - check_remote ret interpreter end diff --git a/test/soml/parfait/test_integer.rb b/test/soml/parfait/test_integer.rb index 5c4912fd..05f8e37a 100644 --- a/test/soml/parfait/test_integer.rb +++ b/test/soml/parfait/test_integer.rb @@ -28,55 +28,17 @@ class TestPutiRT < MiniTest::Test check 10 % 4 end - # if you multiply i by "by" the return is the high 32 bits - def high_times( i , by_high , by_low) - by = by_high * 65536 + by_low - by *= i - by /= 65536 - by /= 65536 - return by + + # finally settled on the long hackers delight version http://www.hackersdelight.org/divcMore.pdf + def test_div10_random + 1000.times do + i = rand 0xfffff + @main = "return #{i}.div10()" + check_local i / 10 + puts "tested #{i}" + end end - # if you multiply i by "by" the return is the low 32 bits - def low_times( i , by_high , by_low) - by = by_high * 65536 + by_low - by *= i - return (by & 0xffffffff) - end - - def test_hightimes2 - @main = "return 2.high_times(12 , 333)" - check high_times(2,12,333) - end - def test_hightimes3456 - @main = "return 3456.high_times(12 , 333)" - check high_times(3456,12,333) - end - def test_hightimes234567 - @main = "return 234567.high_times(12 , 333)" - check high_times(234567,12,333) - end - def test_hightimes - @main = "return 234567.high_times(12 , 333)" - check high_times(234567,12,333) - end - def test_lowtimes2 - @main = "return 2.low_times(14 , 33)" - check low_times(2,14,33) - end - def test_lowtimes3456 - @main = "return 3456.low_times(14 , 33)" - check low_times(3456,14,33) - end - def test_lowtimes234567 - @main = "return 234567.low_times(14 , 33)" - check low_times(234567,14,33) - end - - # finally settled on the long version in http://www.sciencezero.org/index.php?title=ARM:_Division_by_10 - # also the last looked good, but some bug is admittedly in all the ones i tried - # (off course the bug is not included in the test, but easy to achieve with random numbers ) - # for high numbers with ending 0 they are all 1 low. Possibly Interpreter bug ? def test_div10_2 @main = "return 2.div10()" check 2 / 10