On Wed, 7 May 2008 you wrote >On 2008–05–06, at 19:58, Chris Hall (via RT) wrote: > >Good news -- from the point of view of repeatability: I get the same >results as you when running your test program on a 64-bit blead perl >(patchlevel 33783). >> The first section shows the effect. Where the integer division is >> exact we >> get the right integer result. Where it is not exact, the result is >> floated, >> with hopeless loss of significance ! >Bad news from the point of view of understanding the phenomenon: I get >the same results as you when I put -Minteger on the 64-bit perl >command line; that is, when arithmetic operations are carried out with >machine integers and fractional parts are truncated. Same if I put - >Mbigint, replacing all machine arithmetic with arbitrary precision >integer operations. > >These modules appear to be behaving themselves: > >domo:64-bit_perl-current$ ./perl -lwe '$x=2**60 + 3; print $x/2 - 2**59' >0 Documentation says that 2**n is a floating value. So you'll find that: $ perl -lwe '$x=2**63 + 27; print $x - 2**63' 0 More interesting is: $ perl -lwe '$x=(1<<62) + 27; print $x - (1<<62)' 27 $ perl -lwe '$x=(1<<62) + 27; print $x/2 - (1<<61)' 0 but when the division is exact: $ perl -lwe '$x=(1<<62) + 26; print $x/2 - (1<<61)' 13 When $x = 2**62 + 27, $x/2 is 2**61 + 13.5 -- forcing that to floating point introduces a bigger error than rounding to 64-bit integer. >domo:64-bit_perl-current$ ./perl -Ilib -Minteger -lwe '$x=2**60 + 3; >print $x/2 - 2**59' >1 umm... this is different from the result when $x/2 is pushed into floating form... which is what one would expect. With -Minteger 2**n is clearly an integer: $ perl -Ilib -Minteger -lwe '$x=(2**62) + 27; print $x - (2**62)' 27 And, since division now truncates: $ perl -Ilib -Minteger -lwe '$x=(2**62) + 27; print $x/2 - (2**61)' 13 >domo:64-bit_perl-current$ ./perl -Ilib -Mbigint -lwe '$x=2**60 + 3; >print $x/2 - 2**59' >1 Similarly: $ perl -Ilib -Mbigint -lwe '$x=(2**62) + 27; print $x/2 - (2**61)' 13 Is the same as -Minteger, but different from the default case. >Can you say why I should be getting the same results from your test >program in all three cases? Not really. If I run my test with -Minteger, I get: a = 0x0FEDCBA987654321 * 9 + i, for i = 0..9 i: d = int(a/9) : a/9 : a%9 : a - d*9 0: 0x0FEDCBA987654321 : 1147797409030816545 : +0 : +0 1: 0x0FEDCBA987654321 : 1147797409030816545 : +1 : +1 2: 0x0FEDCBA987654321 : 1147797409030816545 : +2 : +2 3: 0x0FEDCBA987654321 : 1147797409030816545 : +3 : +3 4: 0x0FEDCBA987654321 : 1147797409030816545 : +4 : +4 5: 0x0FEDCBA987654321 : 1147797409030816545 : +5 : +5 6: 0x0FEDCBA987654321 : 1147797409030816545 : +6 : +6 7: 0x0FEDCBA987654321 : 1147797409030816545 : +7 : +7 8: 0x0FEDCBA987654321 : 1147797409030816545 : +8 : +8 9: 0x0FEDCBA987654322 : 1147797409030816546 : +0 : +0 ______________________________________________________________________ a = 0x0010000000000000 * 2 + i, for i = 0..3 i: d = int(a/2) : a/2 : a%2 : a - d*2 0: 0x0010000000000000 : 4503599627370496 : +0 : +0 1: 0x0010000000000000 : 4503599627370496 : +1 : +1 2: 0x0010000000000001 : 4503599627370497 : +0 : +0 3: 0x0010000000000001 : 4503599627370497 : +1 : +1 which is what you'd expect for truncating integer division... ...and not the same as the default case, where the division is rounded into floating point: a = 0x0FEDCBA987654321 * 9 + i, for i = 0..9 i: d = int(a/9) : a/9 : a%9 : a - d*9 0: 0x0FEDCBA987654321 : 1147797409030816545 : +0 : +0 1: 0x0FEDCBA987654380 : 1.14779740903082e+18 : +1 : -854 <<< !! 2: 0x0FEDCBA987654380 : 1.14779740903082e+18 : +2 : -853 <<< !! 3: 0x0FEDCBA987654380 : 1.14779740903082e+18 : +3 : -852 <<< !! 4: 0x0FEDCBA987654380 : 1.14779740903082e+18 : +4 : -851 <<< !! 5: 0x0FEDCBA987654380 : 1.14779740903082e+18 : +5 : -850 <<< !! 6: 0x0FEDCBA987654380 : 1.14779740903082e+18 : +6 : -849 <<< !! 7: 0x0FEDCBA987654380 : 1.14779740903082e+18 : +7 : -848 <<< !! 8: 0x0FEDCBA987654380 : 1.14779740903082e+18 : +8 : -847 <<< !! 9: 0x0FEDCBA987654322 : 1147797409030816546 : +0 : +0 ______________________________________________________________________ a = 0x0010000000000000 * 2 + i, for i = 0..3 i: d = int(a/2) : a/2 : a%2 : a - d*2 0: 0x0010000000000000 : 4503599627370496 : +0 : +0 1: 0x0010000000000000 : 4503599627370496 : +1 : +1 2: 0x0010000000000001 : 4503599627370497 : +0 : +0 3: 0x0010000000000002 : 4503599627370498 : +1 : -1 <<< !! Are you getting something else ? Chris -- Chris Hall highwayman.comThread Previous