Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perl version comparison fails #15277

Closed
p5pRT opened this issue Apr 16, 2016 · 6 comments
Closed

Perl version comparison fails #15277

p5pRT opened this issue Apr 16, 2016 · 6 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 16, 2016

Migrated from rt.perl.org#127909 (status was 'rejected')

Searchable as RT127909$

@p5pRT
Copy link
Author

p5pRT commented Apr 16, 2016

From @eserte

This is a bug report for perl from slaven@​rezic.de,
generated with the help of perlbug 1.40 running under perl 5.22.2.


The following oneliner fails​:

$ perl5.22.2-RC1 -e '$ok = $] == 5 + (22/1000) + (2/1000000); !$ok and print "not "; print "ok 1\n"'
not ok 1

I observe this on this freebsd 9.2 system and another linux system (debian/wheezy, also perl 5.22.2-RC1).

What's expected is something like this​:

$ perl5.22.1 -e '$ok = $] == 5 + (22/1000) + (1/1000000); !$ok and print "not "; print "ok 1\n"'
ok 1

I noticed this problem because of failures in Acme-No-0.03 (which is creating
version numbers for comparison like the oneliners above).

Looking at http​://matrix.cpantesters.org/?dist=Acme-No%200.03 it seems that
This problem happens regularily for some perl versions. Indeed​:

$ perl5.14.2 -e '$ok = $] == 5 + (14/1000) + (2/1000000); !$ok and print "not "; print "ok 1\n"'
not ok 1

Maybe a floating point inaccuracy problem?

Regards,
  Slaven



Flags​:
  category=core
  severity=medium


Site configuration information for perl 5.22.2​:

Configured by eserte at Tue Apr 12 07​:39​:08 CEST 2016.

Summary of my perl5 (revision 5 version 22 subversion 2) configuration​:
 
  Platform​:
  osname=freebsd, osvers=9.2-release, archname=amd64-freebsd
  uname='freebsd cvrsnica.herceg.de 9.2-release freebsd 9.2-release #0 r255898​: thu sep 26 22​:50​:31 utc 2013 root@​bake.isc.freebsd.org​:usrobjusrsrcsysgeneric amd64 '
  config_args='-ds -e -Dprefix=/usr/perl5.22.2-RC1sp -Duseshrplib -Dcf_email=srezic@​cpan.org -Doptimize=-O2 -pipe'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=undef, usemultiplicity=undef
  use64bitint=define, use64bitall=define, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_FORTIFY_SOURCE=2',
  optimize='-O2 -pipe',
  cppflags='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
  ccversion='', gccversion='4.2.1 20070831 patched [FreeBSD]', gccosandvers=''
  intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678, doublekind=3
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16, longdblkind=3
  ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='cc', ldflags ='-pthread -Wl,-E -fstack-protector -L/usr/local/lib'
  libpth=/usr/lib /usr/local/lib /usr/include/gcc/4.2 /usr/lib
  libs=-lpthread -lgdbm -lm -lcrypt -lutil -lc
  perllibs=-lpthread -lm -lcrypt -lutil -lc
  libc=, so=so, useshrplib=true, libperl=libperl.so
  gnulibc_version=''
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' -Wl,-R/usr/perl5.22.2-RC1sp/lib/5.22.2/amd64-freebsd/CORE'
  cccdlflags='-DPIC -fPIC', lddlflags='-shared -L/usr/local/lib -fstack-protector'

Locally applied patches​:
  RC1


@​INC for perl 5.22.2​:
  /usr/perl5.22.2-RC1sp/lib/site_perl/5.22.2/amd64-freebsd
  /usr/perl5.22.2-RC1sp/lib/site_perl/5.22.2
  /usr/perl5.22.2-RC1sp/lib/5.22.2/amd64-freebsd
  /usr/perl5.22.2-RC1sp/lib/5.22.2
  .


Environment for perl 5.22.2​:
  HOME=/home/e/eserte
  LANG (unset)
  LANGUAGE (unset)
  LC_ALL=de_DE.UTF-8
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/usr/local/bin​:/usr/bin​:/bin​:/usr/local/sbin​:/usr/sbin​:/sbin​:/home/e/eserte/bin/freebsd9.1​:/home/e/eserte/bin/sh​:/home/e/eserte/bin​:/home/e/eserte/bin/pistachio-perl/bin​:/usr/games​:/home/e/eserte/devel
  PERLDOC=-MPod​::Perldoc​::ToTextOverstrike
  PERL_BADLANG (unset)
  SHELL=/usr/local/bin/zsh

@p5pRT
Copy link
Author

p5pRT commented Apr 16, 2016

From @Leont

On Sat, Apr 16, 2016 at 10​:12 PM, slaven@​rezic.de <perlbug-followup@​perl.org

wrote​:

The following oneliner fails​:

$ perl5.22.2-RC1 -e '$ok = $] == 5 + (22/1000) + (2/1000000); !$ok and
print "not "; print "ok 1\n"'
not ok 1

I observe this on this freebsd 9.2 system and another linux system
(debian/wheezy, also perl 5.22.2-RC1).

What's expected is something like this​:

$ perl5.22.1 -e '$ok = $] == 5 + (22/1000) + (1/1000000); !$ok and print
"not "; print "ok 1\n"'
ok 1

I noticed this problem because of failures in Acme-No-0.03 (which is
creating
version numbers for comparison like the oneliners above).

Looking at http​://matrix.cpantesters.org/?dist=Acme-No%200.03 it seems
that
This problem happens regularily for some perl versions. Indeed​:

$ perl5.14.2 -e '$ok = $] == 5 + (14/1000) + (2/1000000); !$ok and print
"not "; print "ok 1\n"'
not ok 1

Maybe a floating point inaccuracy problem?

Floating point numbers are inherently inaccurate. Using eq instead of ==
gives much better results in general, and using version objects makes == do
something similar to eq too.

Leon

@p5pRT
Copy link
Author

p5pRT commented Apr 16, 2016

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Apr 16, 2016

From @eserte

Dana Sub 16. Tra 2016, 13​:42​:13, LeonT reče​:

On Sat, Apr 16, 2016 at 10​:12 PM, slaven@​rezic.de <perlbug-followup@​perl.org

wrote​:

The following oneliner fails​:

$ perl5.22.2-RC1 -e '$ok = $] == 5 + (22/1000) + (2/1000000); !$ok and
print "not "; print "ok 1\n"'
not ok 1

I observe this on this freebsd 9.2 system and another linux system
(debian/wheezy, also perl 5.22.2-RC1).

What's expected is something like this​:

$ perl5.22.1 -e '$ok = $] == 5 + (22/1000) + (1/1000000); !$ok and print
"not "; print "ok 1\n"'
ok 1

I noticed this problem because of failures in Acme-No-0.03 (which is
creating
version numbers for comparison like the oneliners above).

Looking at http​://matrix.cpantesters.org/?dist=Acme-No%200.03 it seems
that
This problem happens regularily for some perl versions. Indeed​:

$ perl5.14.2 -e '$ok = $] == 5 + (14/1000) + (2/1000000); !$ok and print
"not "; print "ok 1\n"'
not ok 1

Maybe a floating point inaccuracy problem?

Floating point numbers are inherently inaccurate. Using eq instead of ==
gives much better results in general, and using version objects makes == do
something similar to eq too.

OK, I see now that this problem is already mentioned in $]'s entry in perlvar.pod.
Probably this report should be moved over to Acme-No's RT queue...

Regards,
  Slaven

@p5pRT
Copy link
Author

p5pRT commented Apr 16, 2016

From zefram@fysh.org

slaven@​rezic.de 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'
5.0220019999999996329620444157626479864120483398437500000000000000000000
5.0220020000000005211404641158878803253173828125000000000000000000000000

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)

-zefram

@p5pRT p5pRT closed this as completed Apr 18, 2016
@p5pRT
Copy link
Author

p5pRT commented Apr 18, 2016

@iabyn - Status changed from 'open' to 'rejected'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant