develooper Front page | perl.perl5.porters | Postings from April 2016

Re: [perl #127909] Perl version comparison fails

Thread Previous | Thread Next
April 16, 2016 22:38
Re: [perl #127909] Perl version comparison fails
Message ID: wrote:
>$ perl5.22.2-RC1 -e '$ok = $] == 5 + (22/1000) + (2/1000000); !$ok and print "not "; print "ok 1\n"'
>not ok 1

Not a bug; your computation of the comparand is faulty.

$ perl -lwe 'printf "%.70f\n"x2, 5.022002, 5+22e-3+2e-6'

Like most of our version numbers, the numerical value 5.022002 cannot
be represented exactly as a terminating binary fraction, and therefore
cannot be represented exactly as an NV.  The first of the two values
above is the closest available IEEE double to the version number.
The second is a less close approximation.  Your method of computation
is subject to multiple rounding, so in general cannot be expected to
produce a correctly-rounded result.

Nowadays $]'s numerical value is determined by correctly rounding the
decimal fraction.  But it was not always so: prior to somewhere around
5.10, $] was computed by exactly the faulty method you have used.
On an IEEE-double build, the discrepancy can be seen on version 5.6.2,
for example.  I raised this issue in [perl #72210], in which it turned
out to have already been fixed.  To work around this bug, it's best to
stringify $] for any numeric comparison, to get a single decimal->binary
conversion (and so a single rounding operation), working from $]'s string
value which is reliably correct.

For a numeric comparison that can be expected to match on all modern
perls, you want to arrange for a single conversion from decimal, as in

	$] == sprintf("%d.%03d%03d", 5, 22, 2)

To have the numeric comparison work on older perls too, force
re-conversion of $] as I described above:

	"$]" == sprintf("%d.%03d%03d", 5, 22, 2)


Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About