The problem is that when perl prints these numbers out it first rounds them to 15 digits - hence perl prints out the same figure for each of the 2 values featured in the above one-liner, even though perl knows that the 2 values are different:C:\>perl -le "print 'ok' if 3335.9999999999995 > 3335.999999999999;" ok
# In JavaScript, if you try to add 3335.9999999999995 + 0.0000000000001, it is equal to 3335.9999999999995C:\>perl -le "print 3335.9999999999995; print 3335.999999999999;" 3336 3336
Again, the problem is perl's commitment to outputting an approximation:C:>perl -le "print 'ok' if 3335.9999999999995 + 0.0000000000001 == 333 +5.9999999999995;" ok
# "print" won't display the last significant digitC:\>perl -le "print 3335.9999999999995;" 3336
If you want to go to the trouble of installing Math::MPFR (which requires gmp and mpfr C libraries), I've just added an nvtoa() function which will return a string representation of an NV using as few digits as are necessary. (The nvtoa function requires mpfr-4.0.0 or later.)printf "%a", $float; or printf "%.16e", $float;
Works with __float128 and long double builds, too - though Math-MPFR-4.09 (latest CPAN release) is somewhat slower than it ought to be for these nvtypes when abs(exponent) > about 500.C:\>perl -MMath::MPFR=":mpfr" -le "print nvtoa(2 ** -1074);" 5e-324 C:\>perl -MMath::MPFR=":mpfr" -le "print nvtoa(sqrt 2.0);" 1.4142135623730951
instead of :use POSIX qw(strtod); $x = strtod('1234e-5');
Or, you can also use Math::MPFR:$x = 1234e-5;
# So, in order to get the same result you would get in JavaScript, you would call FMOD() function (see below) instead of using the % (mod) operatoruse Math::MPFR qw(:mpfr); $x = atonv('1234e-5');
In reply to Re^4: Variables are automatically rounded off in perl
by syphilis
in thread Variables are automatically rounded off in perl
by Anonymous Monk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |