in reply to Re^3: Variables are automatically rounded off in perl
in thread Variables are automatically rounded off in perl
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');
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^5: Variables are automatically rounded off in perl
by syphilis (Archbishop) on Feb 11, 2019 at 11:23 UTC |