On Mon, Feb 10, 2003 at 11:32:21PM -0000, abigail@abigail.nl (via RT) wrote: Given that it's 5.8.0 with 64 bit IVs > $ perl -wle 'print 1597009560 * 1597009560' > 2550439534731393600 multiplication will be done as IVs as it doesn't overflow (constant folding irrelevant here) > $ perl -wle '$x = 1597009560; print $x * $x' > 2550439534731393600 multiplication will be done as IVs as it doesn't overflow > $ perl -wle 'print 1597009560 ** 2' > 2550439534731393600 exponentiation will be done as NVs It will be constant folded in the peephole optimiser in op.c: #ifdef PERL_PRESERVE_IVUV /* Only bother to attempt to fold to IV if most operators will benefit */ SvIV_please(sv); #endif IIRC this isn't quite the same constant folding as 5.6.x did. > $ perl -wle '$x = 1597009560; print $x ** 2' > 2.5504395347313936e+18 > > I would have expected all outputs to be the same. So would I, but stopping to think, I know what the implementation is up to. > The fact that 2550439534731393600 is numerically the same as > 2.5504395347313936e+18 doesn't do me any good, as it's the > stringifaction that gives the unexpected results: > > $ perl -wle '$x = 1597009560; print "$x ** 2 = @{[$x ** 2]}"' > 1597009560 ** 2 = 2.5504395347313936e+18 > > This is probably caused by the fact that $x ** 2 becomes an NV, > but neither 1597009560 ** 2 nor $x * $x do: If anything, the peephole optimiser should be changed, and the constant 1597009560 ** 2 left as an NV. This would make the first two the same, and the second two both scientific notation. > It seems like in one case (at compile time?), Perl seems to be smart enough > to realize that 1597009560 ** 2 can be represented as an integer, while > in another case, it doesn't figure it out. Correctly deduced, assuming my explanation is correct. Not switching printf to integer format was needed to preserve sanity for values > 2**53 with 64 bit NVs and 64 bit IVs. Your configuration has long double NVs, so I'm not sure if it would be possible to change things whilst maintaining numeric sanity. Sanity here being that exp (37) / 2 should not be an integer. Actually, currently we have insanity: $ perl5.8.0-64 -le 'print exp (37)/2' 5859571186401306 $ perl5.8.0-64 -le 'print exp (shift) /2' 37 5.85957118640131e+15 I would consider only the latter answer sane. Nicholas ClarkThread Previous | Thread Next