Closed p5pRT closed 7 years ago
I'm using the current version of Perl for CentOS el6 (5.10.1).
After moving to x64 architecture the behaviour of sprintf has been changed.
On this platform (x86) the output is like the following:
# perl -e 'printf("%.2f"\, 6.685);' 6.68
But on the other (x64) platform I got this:
# perl -e 'printf("%.2f"\, 6.685);' 6.69
I concatenated the output of perlbug from the x64 platform:
!!!!!!!!!!!!!!! BEGIN x64 !!!!!!!!!!!!!!!!!!!!!!!!!
--- Flags: category=core severity=low --- This perlbug was built using Perl 5.10.1 in the Fedora build system. It is being executed now by Perl 5.10.1 - Fri Jun 22 13:26:34 UTC 2012.
Site configuration information for perl 5.10.1:
Configured by Red Hat\, Inc. at Fri Jun 22 13:26:34 UTC 2012.
Summary of my perl5 (revision 5 version 10 subversion 1) configuration:
Platform: osname=linux\, osvers=2.6.32-220.el6.x86_64\, archname=x86_64-linux-thread-multi uname='linux c6b7.bsys.dev.centos.org 2.6.32-220.el6.x86_64 #1 smp tue dec 6 19:48:22 gmt 2011 x86_64 x86_64 x86_64 gnulinux ' config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -DDEBUGGING=-g -Dversion=5.10.1 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat\, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5 -Darchlib=/usr/lib64/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Dvendorarch=/usr/lib64/perl5/vendor_perl -Dinc_version_list=5.10.0 -Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -! Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize' hint=recommended\, useposix=true\, d_sigaction=define useithreads=define\, usemultiplicity=define useperlio=define\, d_sfio=undef\, uselargefiles=define\, usesocks=undef use64bitint=define\, use64bitall=define\, uselongdouble=undef usemymalloc=n\, bincompat5005=undef Compiler: cc='gcc'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\, optimize='-O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'\, cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion=''\, gccversion='4.4.6 20120305 (Red Hat 4.4.6-4)'\, gccosandvers='' intsize=4\, longsize=8\, ptrsize=8\, doublesize=8\, byteorder=12345678 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=16 ivtype='long'\, ivsize=8\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8 alignbytes=8\, prototype=define Linker and Libraries: ld='gcc'\, ldflags =' -fstack-protector' libpth=/usr/local/lib64 /lib64 /usr/lib64 libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=\, so=so\, useshrplib=true\, libperl=libperl.so gnulibc_version='2.12' Dynamic Linking: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E -Wl\,-rpath\,/usr/lib64/perl5/CORE' cccdlflags='-fPIC'\, lddlflags='-shared -O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'
Locally applied patches:
--- @INC for perl 5.10.1: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .
--- Environment for perl 5.10.1: HOME=/root LANG=en_US.UTF-8 LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin PERL_BADLANG (unset) SHELL=/bin/bash
!!!!!!!!!!!!!!! END x64 !!!!!!!!!!!!!!!!!!!!!!!!!
x32 platform-related stuff:
On Mon Oct 01 04:32:45 2012\, bk@starlink.ru wrote:
This is a bug report for perl from bk@starlink.ru\, generated with the help of perlbug 1.39 running under perl 5.10.1.
----------------------------------------------------------------- [Please describe your issue here]
I'm using the current version of Perl for CentOS el6 (5.10.1).
After moving to x64 architecture the behaviour of sprintf has been changed.
On this platform (x86) the output is like the following:
# perl -e 'printf("%.2f"\, 6.685);' 6.68
But on the other (x64) platform I got this:
# perl -e 'printf("%.2f"\, 6.685);' 6.69
I concatenated the output of perlbug from the x64 platform:
!!!!!!!!!!!!!!! BEGIN x64 !!!!!!!!!!!!!!!!!!!!!!!!!
--- Flags: category=core severity=low --- This perlbug was built using Perl 5.10.1 in the Fedora build system. It is being executed now by Perl 5.10.1 - Fri Jun 22 13:26:34 UTC 2012.
Site configuration information for perl 5.10.1:
Configured by Red Hat\, Inc. at Fri Jun 22 13:26:34 UTC 2012.
Summary of my perl5 (revision 5 version 10 subversion 1) configuration:
Platform: osname=linux\, osvers=2.6.32-220.el6.x86_64\, archname=x86_64-linux- thread-multi uname='linux c6b7.bsys.dev.centos.org 2.6.32-220.el6.x86_64 #1 smp tue dec 6 19:48:22 gmt 2011 x86_64 x86_64 x86_64 gnulinux ' config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -DDEBUGGING=-g -Dversion=5.10.1 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat\, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5 -Darchlib=/usr/lib64/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Dvendorarch=/usr/lib64/perl5/vendor_perl -Dinc_version_list=5.10.0 -Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -! Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize' hint=recommended\, useposix=true\, d_sigaction=define useithreads=define\, usemultiplicity=define useperlio=define\, d_sfio=undef\, uselargefiles=define\, usesocks=undef use64bitint=define\, use64bitall=define\, uselongdouble=undef usemymalloc=n\, bincompat5005=undef Compiler: cc='gcc'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\, optimize='-O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'\, cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion=''\, gccversion='4.4.6 20120305 (Red Hat 4.4.6-4)'\, gccosandvers='' intsize=4\, longsize=8\, ptrsize=8\, doublesize=8\, byteorder=12345678 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=16 ivtype='long'\, ivsize=8\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8 alignbytes=8\, prototype=define Linker and Libraries: ld='gcc'\, ldflags =' -fstack-protector' libpth=/usr/local/lib64 /lib64 /usr/lib64 libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=\, so=so\, useshrplib=true\, libperl=libperl.so gnulibc_version='2.12' Dynamic Linking: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E -Wl\,-rpath\,/usr/lib64/perl5/CORE' cccdlflags='-fPIC'\, lddlflags='-shared -O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'
Locally applied patches:
--- @INC for perl 5.10.1: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .
--- Environment for perl 5.10.1: HOME=/root LANG=en_US.UTF-8 LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset)
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin PERL_BADLANG (unset) SHELL=/bin/bash
!!!!!!!!!!!!!!! END x64 !!!!!!!!!!!!!!!!!!!!!!!!!
x32 platform-related stuff:
[Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=core severity=low --- This perlbug was built using Perl 5.10.1 in the Fedora build system. It is being executed now by Perl 5.10.1 - Sun Nov 6 00:21:10 GMT 2011.
Site configuration information for perl 5.10.1:
Configured by Red Hat\, Inc. at Sun Nov 6 00:21:10 GMT 2011.
Summary of my perl5 (revision 5 version 10 subversion 1) configuration:
Platform: osname=linux\, osvers=2.6.32-44.2.el6.x86_64\, archname=i386-linux- thread-multi uname='linux c6b5.bsys.dev.centos.org 2.6.32-44.2.el6.x86_64 #1 smp wed jul 21 12:48:32 edt 2010 i686 i686 i386 gnulinux ' config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -DDEBUGGING=-g -Dversion=5.10.1 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat\, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib/perl5 -Dprivlib=/usr/share/perl5 -Darchlib=/usr/lib/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Dvendorarch=/usr/lib/perl5/vendor_perl -Dinc_version_list=5.10.0 -Darchname=i386-linux-thread-multi -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_! r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin' hint=recommended\, useposix=true\, d_sigaction=define useithreads=define\, usemultiplicity=define useperlio=define\, d_sfio=undef\, uselargefiles=define\, usesocks=undef use64bitint=undef\, use64bitall=undef\, uselongdouble=undef usemymalloc=n\, bincompat5005=undef Compiler: cc='gcc'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\, optimize='-O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables'\, cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion=''\, gccversion='4.4.5 20110214 (Red Hat 4.4.5-6)'\, gccosandvers='' intsize=4\, longsize=4\, ptrsize=4\, doublesize=8\, byteorder=1234 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=12 ivtype='long'\, ivsize=4\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8 alignbytes=4\, prototype=define Linker and Libraries: ld='gcc'\, ldflags =' -fstack-protector -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=/lib/libc-2.12.so\, so=so\, useshrplib=true\, libperl=libperl.so gnulibc_version='2.12' Dynamic Linking: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E -Wl\,-rpath\,/usr/lib/perl5/CORE' cccdlflags='-fPIC'\, lddlflags='-shared -O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -L/usr/local/lib'
Locally applied patches:
--- @INC for perl 5.10.1: /usr/local/lib/perl5 /usr/local/share/perl5 /usr/lib/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib/perl5 /usr/share/perl5 .
--- Environment for perl 5.10.1: HOME=/root LANG=ru_RU.UTF-8 LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset)
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin PERL_BADLANG (unset) SHELL=/bin/bash
Three preliminary notes:
1. Have you ruled out any other possible cause of this difference? I notice that you are using different versions of gcc on the two platforms.
2. You are running an older\, unsupported version of Perl. Can you run this with either 5.14 or 5.16? (Note: I'm not saying the Perl version is the cause of the difference. It's just that a flaw in 5.10 is not going to be corrected.)
3. At the moment I have no x86_64 machine available. I do have a Darwin/PPC and a Linux/i386. Both are running Perl 5.16\, but they're probably running different versions of gcc. I get:
Darwin/PPC:
perl -E 'printf("%.2f"\, 6.685);' 6.69
Linux/i386:
perl -E 'printf("%.2f"\, 6.685);' 6.68
I suspect that the differences in the rounding is not Perl's problems -- but there are others on list who can speak better to that.
Thank you very much. Jim Keenan
The RT System itself - Status changed from 'new' to 'open'
On Mon\, Oct 1\, 2012 at 10:22 PM\, James E Keenan via RT \< perlbug-followup@perl.org> wrote:
On Mon Oct 01 04:32:45 2012\, bk@starlink.ru wrote:
This is a bug report for perl from bk@starlink.ru\, generated with the help of perlbug 1.39 running under perl 5.10.1.
----------------------------------------------------------------- [Please describe your issue here]
I'm using the current version of Perl for CentOS el6 (5.10.1).
After moving to x64 architecture the behaviour of sprintf has been changed.
On this platform (x86) the output is like the following:
# perl -e 'printf("%.2f"\, 6.685);' 6.68
But on the other (x64) platform I got this:
# perl -e 'printf("%.2f"\, 6.685);' 6.69
Three preliminary notes:
1. Have you ruled out any other possible cause of this difference? I notice that you are using different versions of gcc on the two platforms.
2. You are running an older\, unsupported version of Perl. Can you run this with either 5.14 or 5.16? (Note: I'm not saying the Perl version is the cause of the difference. It's just that a flaw in 5.10 is not going to be corrected.)
3. At the moment I have no x86_64 machine available. I do have a Darwin/PPC and a Linux/i386. Both are running Perl 5.16\, but they're probably running different versions of gcc. I get:
Darwin/PPC:
perl -E 'printf("%.2f"\, 6.685);' 6.69
Linux/i386:
perl -E 'printf("%.2f"\, 6.685);' 6.68
I suspect that the differences in the rounding is not Perl's problems -- but there are others on list who can speak better to that.
Thank you very much. Jim Keenan
For what it's worth\, I get the same behavior in javascript on Google Chrome on a 64-bit platform\, because 6.685 is stored internally as:
"6.68499999999999960920"
Try perl -E 'printf("%.20f"\, 6.685)' to see what you're actually storing - the nearest number to 6.685 may be very slightly less than 6.685\, and hence round down.
I don't have a 32-bit platform to test at hand\, but I'd guess that on a 32-bit platform it's something more like:
"6.68500000000000000001"
It's more of a floating point gotcha than a perl issue.
via perlbug: queue: perl5 status: new https://rt-archive.perl.org/perl5/Ticket/Display.html?id=11509 2
On Tue\, Oct 2\, 2012 at 4:58 PM\, Peter Martini \petercmartini@​gmail\.com wrote:
For what it's worth\, I get the same behavior in javascript on Google Chrome on a 64-bit platform\, because 6.685 is stored internally as:
"6.68499999999999960920"
Try perl -E 'printf("%.20f"\, 6.685)' to see what you're actually storing - the nearest number to 6.685 may be very slightly less than 6.685\, and hence round down.
I don't have a 32-bit platform to test at hand\, but I'd guess that on a 32-bit platform it's something more like:
"6.68500000000000000001"
He got the higher result on the x64 than the x86\, so that makes no sense. Why would the lower number give the higher rounded result?
On Oct 2\, 2012 5:37 PM\, "Eric Brine" \ikegami@​adaelis\.com wrote:
On Tue\, Oct 2\, 2012 at 4:58 PM\, Peter Martini \petercmartini@​gmail\.com wrote:
For what it's worth\, I get the same behavior in javascript on Google Chrome on a 64-bit platform\, because 6.685 is stored internally as:
"6.68499999999999960920"
Try perl -E 'printf("%.20f"\, 6.685)' to see what you're actually storing - the nearest number to 6.685 may be very slightly less than 6.685\, and hence round down.
I don't have a 32-bit platform to test at hand\, but I'd guess that on a 32-bit platform it's something more like:
"6.68500000000000000001"
He got the higher result on the x64 than the x86\, so that makes no sense. Why would the lower number give the higher rounded result?
Ah. I wasn't paying enough attention to which was which. Printing to 20 (or 30) places will still show different approximations of 6.685 though\, depending on the fp hardware - can that be confirmed?
2.275 is another good one to test (if I recall correctly)
On Oct 2\, 2012 5:48 PM\, "Peter Martini" \petercmartini@​gmail\.com wrote:
On Oct 2\, 2012 5:37 PM\, "Eric Brine" \ikegami@​adaelis\.com wrote:
On Tue\, Oct 2\, 2012 at 4:58 PM\, Peter Martini \petercmartini@​gmail\.com wrote:
For what it's worth\, I get the same behavior in javascript on Google Chrome on a 64-bit platform\, because 6.685 is stored internally as:
"6.68499999999999960920"
Try perl -E 'printf("%.20f"\, 6.685)' to see what you're actually storing - the nearest number to 6.685 may be very slightly less than 6.685\, and hence round down.
I don't have a 32-bit platform to test at hand\, but I'd guess that on a 32-bit platform it's something more like:
"6.68500000000000000001"
He got the higher result on the x64 than the x86\, so that makes no sense. Why would the lower number give the higher rounded result?
Ah. I wasn't paying enough attention to which was which. Printing to 20 (or 30) places will still show different approximations of 6.685 though\, depending on the fp hardware - can that be confirmed?
2.275 is another good one to test (if I recall correctly)
Yep\, tested on my android phone:
javascript:alert(2.275.toFixed(2))
displays 2.27.
My original test was Windows 7 Chrome\, and I'm pretty sure 64bit\, but not positive.
On Tue\, Oct 2\, 2012 at 5:37 PM\, Eric Brine \ikegami@​adaelis\.com wrote:
On Tue\, Oct 2\, 2012 at 4:58 PM\, Peter Martini \petercmartini@​gmail\.com wrote:
For what it's worth\, I get the same behavior in javascript on Google Chrome on a 64-bit platform\, because 6.685 is stored internally as:
"6.68499999999999960920"
Try perl -E 'printf("%.20f"\, 6.685)' to see what you're actually storing - the nearest number to 6.685 may be very slightly less than 6.685\, and hence round down.
I don't have a 32-bit platform to test at hand\, but I'd guess that on a 32-bit platform it's something more like:
"6.68500000000000000001"
He got the higher result on the x64 than the x86\, so that makes no sense. Why would the lower number give the higher rounded result?
More machines:
(pmdesktop is 64-bit)
[peter@pmdesktop ~]$ perl -e 'printf "%.02f / %.30f\n"\, 6.685\, 6.685' 6.69 / 6.685000000000000497379915032070
(pmlinlaptop is 32-bit)
peter@pmlinlaptop:\~$ perl -e 'printf "%.02f / %.30f\n"\, 6.685\, 6.685' 6.68 / 6.684999999999999609201495331945
So the Chrome I was using at the time was probably 32-bit after all. Should have double checked :-)
On Tue\, Oct 2\, 2012 at 6:33 PM\, Peter Martini \petercmartini@​gmail\.com wrote:
(pmdesktop is 64-bit) [peter@pmdesktop ~]$ perl -e 'printf "%.02f / %.30f\n"\, 6.685\, 6.685' 6.69 / 6.685000000000000497379915032070
(This is perl 5\, version 16\, subversion 0 (v5.16.0) built for x86_64-linux-thread-multi) $ perl -e 'printf "%.02f / %.30f\n"\, 6.685\, 6.685' 6.68 / 6.684999999999999609201495331945
On Tue Oct 02 15:33:57 2012\, pcm wrote:
On Tue\, Oct 2\, 2012 at 5:37 PM\, Eric Brine \ikegami@​adaelis\.com wrote:
On Tue\, Oct 2\, 2012 at 4:58 PM\, Peter Martini \petercmartini@​gmail\.com wrote:
For what it's worth\, I get the same behavior in javascript on Google Chrome on a 64-bit platform\, because 6.685 is stored internally as:
"6.68499999999999960920"
Try perl -E 'printf("%.20f"\, 6.685)' to see what you're actually storing - the nearest number to 6.685 may be very slightly less than 6.685\, and hence round down.
I don't have a 32-bit platform to test at hand\, but I'd guess that on a 32-bit platform it's something more like:
"6.68500000000000000001"
He got the higher result on the x64 than the x86\, so that makes no sense. Why would the lower number give the higher rounded result?
More machines:
(pmdesktop is 64-bit)
[peter@pmdesktop ~]$ perl -e 'printf "%.02f / %.30f\n"\, 6.685\, 6.685' 6.69 / 6.685000000000000497379915032070
(pmlinlaptop is 32-bit)
peter@pmlinlaptop:\~$ perl -e 'printf "%.02f / %.30f\n"\, 6.685\, 6.685' 6.68 / 6.684999999999999609201495331945
So the Chrome I was using at the time was probably 32-bit after all. Should have double checked :-)
JavaScript should give the same result regardless of platform. ECMAScript is pretty strict about how floating-point operations work.
JE is probably the only non-compliant implementation.
--
Father Chrysostomos
This is perl 5\, version 14\, subversion 2 (v5.14.2) built for MSWin32-x86-multi-thread
perl -e"printf qq{%.02f / %.30f\n}\, 6.685\, 6.685 6.69 / 6.685000000000000500000000000000
This is perl\, v5.10.1 (*) built for i686-cygwin-thread-multi-64int
$ perl -E'say sprintf "%.02f / %.30f\n"\, 6.685\, 6.685' 6.68 / 6.684999999999999609201495331945
(Both on the same 64-bit Win7 machine)
----- Original Message ----- From: "Eric Brine" \ikegami@​adaelis\.com To: "Peter Martini" \petercmartini@​gmail\.com Cc: \perlbug\-followup@​perl\.org; \bk@​starlink\.ru; \perl5\-porters@​perl\.org Sent: Wednesday\, October 03\, 2012 9:13 AM Subject: Re: [perl #115092] Rounding a floating point number
On Tue\, Oct 2\, 2012 at 6:33 PM\, Peter Martini \petercmartini@​gmail\.com wrote:
(pmdesktop is 64-bit) [peter@pmdesktop ~]$ perl -e 'printf "%.02f / %.30f\n"\, 6.685\, 6.685' 6.69 / 6.685000000000000497379915032070
(This is perl 5\, version 16\, subversion 0 (v5.16.0) built for x86_64-linux-thread-multi) $ perl -e 'printf "%.02f / %.30f\n"\, 6.685\, 6.685' 6.68 / 6.684999999999999609201495331945
FWIW\, for perls built with nvsize=8\, I get the same as Eric on both Linux (32-bit only) and Windows (32-bit and 64-bit). For perls built with nvsize=12\, I get a slightly different value for %.30f:
6.684999999999999999947958295721
but it's still less than 6.685\, and rounds to 6.68.
However\, perhaps Peter's perl has an nvsize that is neither 8 nor 12 ?
On MS Windows\, I can use Math::LongDouble to effectively obtain long double precision:
########################################### C:\_32>perl -MMath::LongDouble=":all" -e "$x=Math::LongDouble->new(6.685);print LDtoSTRP($x\, 31)" 6.684999999999999999947958295721e+000 ###########################################
Cheers\, Rob
----- Original Message ----- From: "Eric Brine" \ikegami@​adaelis\.com To: "Peter Martini" \petercmartini@​gmail\.com Cc: \perlbug\-followup@​perl\.org; \bk@​starlink\.ru; \perl5\-porters@​perl\.org Sent: Wednesday\, October 03\, 2012 9:19 AM Subject: Re: [perl #115092] Rounding a floating point number
This is perl 5\, version 14\, subversion 2 (v5.14.2) built for MSWin32-x86-multi-thread
perl -e"printf qq{%.02f / %.30f\n}\, 6.685\, 6.685 6.69 / 6.685000000000000500000000000000
Heh ... I didn't try ActivePerl ... but when I do\, I get the same:
C:\_32>perl -e "printf \"%.02f / %.30f\n\"\, 6.685\, 6.685" 6.69 / 6.685000000000000500000000000000
Cheers\, Rob
On Tue\, 02 Oct 2012\, Sisyphus wrote:
FWIW\, for perls built with nvsize=8\, I get the same as Eric on both Linux (32-bit only) and Windows (32-bit and 64-bit). For perls built with nvsize=12\, I get a slightly different value for %.30f:
6.684999999999999999947958295721
but it's still less than 6.685\, and rounds to 6.68.
However\, perhaps Peter's perl has an nvsize that is neither 8 nor 12 ?
You may want to play around with the FPU rounding mode as well:
http://msdn.microsoft.com/en-us/library/e9b52ceh%28v=vs.80%29.aspx
It is possible that a different RTL has set up a different rounding mode.
We do initialize the error mode on Windows to be independent of the RTL\, but maybe we should also select a default rounding mode:
/* Disable floating point errors\, Perl will trap the ones we * care about. VC++ RTL defaults to switching these off * already\, but some RTLs don't. Since we don't * want to be at the vendor's whim on the default\, we set * it explicitly here. */ #if !defined(__GNUC__) _control87(MCW_EM\, MCW_EM); #endif
Cheers\, -Jan
On Oct 2\, 2012 8:31 PM\, "Jan Dubois" \jand@​activestate\.com wrote:
On Tue\, 02 Oct 2012\, Sisyphus wrote:
FWIW\, for perls built with nvsize=8\, I get the same as Eric on both Linux (32-bit only) and Windows (32-bit and 64-bit). For perls built with nvsize=12\, I get a slightly different value for %.30f:
6.684999999999999999947958295721
but it's still less than 6.685\, and rounds to 6.68.
However\, perhaps Peter's perl has an nvsize that is neither 8 nor 12 ?
You may want to play around with the FPU rounding mode as well:
http://msdn.microsoft.com/en-us/library/e9b52ceh%28v=vs.80%29.aspx
It is possible that a different RTL has set up a different rounding mode.
We do initialize the error mode on Windows to be independent of the RTL\, but maybe we should also select a default rounding mode:
/\* Disable floating point errors\, Perl will trap the ones we \* care about\. VC\+\+ RTL defaults to switching these off \* already\, but some RTLs don't\. Since we don't \* want to be at the vendor's whim on the default\, we set \* it explicitly here\. \*/
#if !defined(__GNUC__) _control87(MCW_EM\, MCW_EM); #endif
Would the rounding mode affect the atof? (honest question\, I don't know where it does its thing). The issue is the closest approximation is sometimes on the high side and sometimes on the low side\, depending on nvsize - and no matter what size you're using\, there will be numbers that round "wrong".
2.275 bit me in a javascript project years ago\, since it rounds to 2.27\, and that was enough for me to take seriously its limitations. Which means I don't think there's anything for us to do here. But javascripts standard size does get the op's example right :-)
Cheers\, -Jan
On Oct 2\, 2012 8:31 PM\, "Jan Dubois" \jand@​activestate\.com wrote:
On Tue\, 02 Oct 2012\, Sisyphus wrote:
FWIW\, for perls built with nvsize=8\, I get the same as Eric on both Linux (32-bit only) and Windows (32-bit and 64-bit). For perls built with nvsize=12\, I get a slightly different value for %.30f:
6.684999999999999999947958295721
but it's still less than 6.685\, and rounds to 6.68.
However\, perhaps Peter's perl has an nvsize that is neither 8 nor 12 ?
You may want to play around with the FPU rounding mode as well:
http://msdn.microsoft.com/en-us/library/e9b52ceh%28v=vs.80%29.aspx
It is possible that a different RTL has set up a different rounding mode.
We do initialize the error mode on Windows to be independent of the RTL\, but maybe we should also select a default rounding mode:
/\* Disable floating point errors\, Perl will trap the ones we \* care about\. VC\+\+ RTL defaults to switching these off \* already\, but some RTLs don't\. Since we don't \* want to be at the vendor's whim on the default\, we set \* it explicitly here\. \*/
#if !defined(__GNUC__) _control87(MCW_EM\, MCW_EM); #endif
Cheers\, -Jan
So\, do we have a Perl bug here?
On Tue Oct 02 18:15:43 2012\, jkeenan wrote:
So\, do we have a Perl bug here?
Maybe. Could someone who sees different behaviour with different perls try replacing 6.685 with POSIX::strtod("6.685")?
If the answer then becomes the same with different perls\, then I suspect this is a duplicate of #41202.
--
Father Chrysostomos
On Tue\, Oct 2\, 2012 at 9:21 PM\, Father Chrysostomos via RT \< perlbug-followup@perl.org> wrote:
On Tue Oct 02 18:15:43 2012\, jkeenan wrote:
So\, do we have a Perl bug here?
Maybe. Could someone who sees different behaviour with different perls try replacing 6.685 with POSIX::strtod("6.685")?
If the answer then becomes the same with different perls\, then I suspect this is a duplicate of #41202.
On my 64-bit machine:
perl -E 'use POSIX qw(strtod); printf "%.02f\, %.02f\n"\, 6.685\, strtod("6.685");' 6.69\, 6.68
perl -E 'use POSIX qw(strtod); printf "%.020f\, %.020f\n"\, 6.685\, strtod("6.685");' 6.68500000000000049738\, 6.68499999999999960920
And for good measure\, on that same machine:
File a.cpp
#include \
int main(){ cout \<\< setprecision(40) \<\< strtof("6.685"\,0) \<\< endl; cout \<\< setprecision(40) \<\< strtod("6.685"\,0) \<\< endl; cout \<\< setprecision(40) \<\< strtold("6.685"\,0) \<\< endl; }
gives me:
6.684999942779541015625 6.684999999999999609201495331944897770882 6.684999999999999999947958295720695787168
So\, I'll dig through and see if where it got that number from. For the record\, both the system perl and one built with ./Configure -Dusedevel -Dusethreads -des do the same thing\, and here's perl -V from the system perl:
Platform: osname=linux\, osvers=2.6.32-220.el6.x86_64\, archname=x86_64-linux-thread-multi uname='linux c6b7.bsys.dev.centos.org 2.6.32-220.el6.x86_64 #1 smp tue dec 6 19:48:22 gmt 2011 x86_64 x86_64 x86_64 gnulinux ' config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size =4 -m64 -mtune=generic -DDEBUGGING=-g -Dversion=5.10.1 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat\, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5 -Darchlib=/usr/lib64/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Dvendorarch=/usr/lib64/perl5/vend or_perl -Dinc_version_list=5.10.0 -Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -D usethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r _proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscri ptdir=/usr/bin -Dusesitecustomize' hint=recommended\, useposix=true\, d_sigaction=define useithreads=define\, usemultiplicity=define useperlio=define\, d_sfio=undef\, uselargefiles=define\, usesocks=undef use64bitint=define\, use64bitall=define\, uselongdouble=undef usemymalloc=n\, bincompat5005=undef Compiler: cc='gcc'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\, optimize='-O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'\, cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion=''\, gccversion='4.4.6 20120305 (Red Hat 4.4.6-4)'\, gccosandvers='' intsize=4\, longsize=8\, ptrsize=8\, doublesize=8\, byteorder=12345678 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=16 ivtype='long'\, ivsize=8\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8 alignbytes=8\, prototype=define Linker and Libraries: ld='gcc'\, ldflags =' -fstack-protector' libpth=/usr/local/lib64 /lib64 /usr/lib64 libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=\, so=so\, useshrplib=true\, libperl=libperl.so gnulibc_version='2.12' Dynamic Linking: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E -Wl\,-rpath\,/usr/lib64/perl5/CORE' cccdlflags='-fPIC'\, lddlflags='-shared -O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'
Characteristics of this binary (from libperl): Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP USE_64_BIT_ALL USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES USE_PERLIO USE_REENTRANT_API USE_SITECUSTOMIZE Built under linux Compiled at Jun 22 2012 13:27:28 @INC: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .
--
Father Chrysostomos
--- via perlbug: queue: perl5 status: open https://rt-archive.perl.org/perl5/Ticket/Display.html?id=115092
On Tue Oct 02 20:41:15 2012\, pcm wrote:
On Tue\, Oct 2\, 2012 at 9:21 PM\, Father Chrysostomos via RT \< perlbug-followup@perl.org> wrote:
On Tue Oct 02 18:15:43 2012\, jkeenan wrote:
So\, do we have a Perl bug here?
Maybe. Could someone who sees different behaviour with different perls try replacing 6.685 with POSIX::strtod("6.685")?
If the answer then becomes the same with different perls\, then I suspect this is a duplicate of #41202.
On my 64-bit machine:
perl -E 'use POSIX qw(strtod); printf "%.02f\, %.02f\n"\, 6.685\, strtod("6.685");' 6.69\, 6.68
perl -E 'use POSIX qw(strtod); printf "%.020f\, %.020f\n"\, 6.685\, strtod("6.685");' 6.68500000000000049738\, 6.68499999999999960920
And for good measure\, on that same machine:
File a.cpp #include \
#include \ #include \ using namespace std; int main(){ cout \<\< setprecision(40) \<\< strtof("6.685"\,0) \<\< endl; cout \<\< setprecision(40) \<\< strtod("6.685"\,0) \<\< endl; cout \<\< setprecision(40) \<\< strtold("6.685"\,0) \<\< endl; }
gives me:
6.684999942779541015625 6.684999999999999609201495331944897770882 6.684999999999999999947958295720695787168
So\, I'll dig through and see if where it got that number from.
If you mean the 6.69\, itâs coming from numeric.c:Perl_grok_number. Perl has itâs own string-to-number conversion which\, er\, doesnât work. Thatâs the subject of ticket #41202. I donât have the expertise to fix it\, and unfortunately it seems nobody here does.
--
Father Chrysostomos
El 03/10/12 03:15\, James E Keenan via RT escribiĂł:
So\, do we have a Perl bug here?
I like the idea for a computer language with True Math...
(just dreaming)
-- JF^D
On Tue\, Oct 2\, 2012 at 9:21 PM\, Father Chrysostomos via RT \perlbug\-followup@​perl\.org wrote:
Maybe. Could someone who sees different behaviour with different perls try replacing 6.685 with POSIX::strtod("6.685")?
Here you go:
[ActivePerl] This is perl 5\, version 14\, subversion 2 (v5.14.2) built for MSWin32-x86-multi-thread
perl -E"say sprintf '%.2f / %.30f'\, (6.685)x2 6.69 / 6.685000000000000500000000000000
perl -MPOSIX=strtod -E"say sprintf '%.2f\, %.30f'\, (''.strtod('6.685'))x2" 6.69\, 6.685000000000000500000000000000
[Cygwin] This is perl\, v5.10.1 (*) built for i686-cygwin-thread-multi-64int
$ perl -E'say sprintf "%.2f / %.30f"\, 6.685\, 6.685' 6.68 / 6.684999999999999609201495331945
$ perl -MPOSIX=strtod -E'say sprintf "%.2f / %.30f"\, ("".strtod("6.685"))x2' 6.68 / 6.684999999999999609201495331945
Both on the same 64-bit Win7 machine.
On 10/02/2012 04:22 AM\, James E Keenan via RT wrote:
On Mon Oct 01 04:32:45 2012\, bk@starlink.ru wrote:
This is a bug report for perl from bk@starlink.ru\, generated with the help of perlbug 1.39 running under perl 5.10.1.
----------------------------------------------------------------- [Please describe your issue here]
I'm using the current version of Perl for CentOS el6 (5.10.1).
After moving to x64 architecture the behaviour of sprintf has been changed.
On this platform (x86) the output is like the following:
# perl -e 'printf("%.2f"\, 6.685);' 6.68
But on the other (x64) platform I got this:
# perl -e 'printf("%.2f"\, 6.685);' 6.69
I concatenated the output of perlbug from the x64 platform:
!!!!!!!!!!!!!!! BEGIN x64 !!!!!!!!!!!!!!!!!!!!!!!!!
--- Flags: category=core severity=low --- This perlbug was built using Perl 5.10.1 in the Fedora build system. It is being executed now by Perl 5.10.1 - Fri Jun 22 13:26:34 UTC 2012.
Site configuration information for perl 5.10.1:
Configured by Red Hat\, Inc. at Fri Jun 22 13:26:34 UTC 2012.
Summary of my perl5 (revision 5 version 10 subversion 1) configuration:
Platform: osname=linux\, osvers=2.6.32-220.el6.x86_64\, archname=x86_64-linux- thread-multi uname='linux c6b7.bsys.dev.centos.org 2.6.32-220.el6.x86_64 #1 smp tue dec 6 19:48:22 gmt 2011 x86_64 x86_64 x86_64 gnulinux ' config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -DDEBUGGING=-g -Dversion=5.10.1 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat\, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5 -Darchlib=/usr/lib64/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Dvendorarch=/usr/lib64/perl5/vendor_perl -Dinc_version_list=5.10.0 -Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -! Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize' hint=recommended\, useposix=true\, d_sigaction=define useithreads=define\, usemultiplicity=define useperlio=define\, d_sfio=undef\, uselargefiles=define\, usesocks=undef use64bitint=define\, use64bitall=define\, uselongdouble=undef usemymalloc=n\, bincompat5005=undef Compiler: cc='gcc'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\, optimize='-O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'\, cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion=''\, gccversion='4.4.6 20120305 (Red Hat 4.4.6-4)'\, gccosandvers='' intsize=4\, longsize=8\, ptrsize=8\, doublesize=8\, byteorder=12345678 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=16 ivtype='long'\, ivsize=8\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8 alignbytes=8\, prototype=define Linker and Libraries: ld='gcc'\, ldflags =' -fstack-protector' libpth=/usr/local/lib64 /lib64 /usr/lib64 libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=\, so=so\, useshrplib=true\, libperl=libperl.so gnulibc_version='2.12' Dynamic Linking: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E -Wl\,-rpath\,/usr/lib64/perl5/CORE' cccdlflags='-fPIC'\, lddlflags='-shared -O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'
Locally applied patches:
--- @INC for perl 5.10.1: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .
--- Environment for perl 5.10.1: HOME=/root LANG=en_US.UTF-8 LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset)
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin PERL_BADLANG (unset) SHELL=/bin/bash
!!!!!!!!!!!!!!! END x64 !!!!!!!!!!!!!!!!!!!!!!!!!
x32 platform-related stuff:
[Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=core severity=low --- This perlbug was built using Perl 5.10.1 in the Fedora build system. It is being executed now by Perl 5.10.1 - Sun Nov 6 00:21:10 GMT 2011.
Site configuration information for perl 5.10.1:
Configured by Red Hat\, Inc. at Sun Nov 6 00:21:10 GMT 2011.
Summary of my perl5 (revision 5 version 10 subversion 1) configuration:
Platform: osname=linux\, osvers=2.6.32-44.2.el6.x86_64\, archname=i386-linux- thread-multi uname='linux c6b5.bsys.dev.centos.org 2.6.32-44.2.el6.x86_64 #1 smp wed jul 21 12:48:32 edt 2010 i686 i686 i386 gnulinux ' config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -DDEBUGGING=-g -Dversion=5.10.1 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat\, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib/perl5 -Dprivlib=/usr/share/perl5 -Darchlib=/usr/lib/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Dvendorarch=/usr/lib/perl5/vendor_perl -Dinc_version_list=5.10.0 -Darchname=i386-linux-thread-multi -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_! r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin' hint=recommended\, useposix=true\, d_sigaction=define useithreads=define\, usemultiplicity=define useperlio=define\, d_sfio=undef\, uselargefiles=define\, usesocks=undef use64bitint=undef\, use64bitall=undef\, uselongdouble=undef usemymalloc=n\, bincompat5005=undef Compiler: cc='gcc'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\, optimize='-O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables'\, cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion=''\, gccversion='4.4.5 20110214 (Red Hat 4.4.5-6)'\, gccosandvers='' intsize=4\, longsize=4\, ptrsize=4\, doublesize=8\, byteorder=1234 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=12 ivtype='long'\, ivsize=4\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8 alignbytes=4\, prototype=define Linker and Libraries: ld='gcc'\, ldflags =' -fstack-protector -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=/lib/libc-2.12.so\, so=so\, useshrplib=true\, libperl=libperl.so gnulibc_version='2.12' Dynamic Linking: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E -Wl\,-rpath\,/usr/lib/perl5/CORE' cccdlflags='-fPIC'\, lddlflags='-shared -O2 -g -pipe -Wall -Wp\,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -L/usr/local/lib'
Locally applied patches:
--- @INC for perl 5.10.1: /usr/local/lib/perl5 /usr/local/share/perl5 /usr/lib/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib/perl5 /usr/share/perl5 .
--- Environment for perl 5.10.1: HOME=/root LANG=ru_RU.UTF-8 LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset)
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin PERL_BADLANG (unset) SHELL=/bin/bash
Three preliminary notes:
1. Have you ruled out any other possible cause of this difference? I notice that you are using different versions of gcc on the two platforms.
2. You are running an older\, unsupported version of Perl. Can you run this with either 5.14 or 5.16? (Note: I'm not saying the Perl version is the cause of the difference. It's just that a flaw in 5.10 is not going to be corrected.)
3. At the moment I have no x86_64 machine available. I do have a Darwin/PPC and a Linux/i386. Both are running Perl 5.16\, but they're probably running different versions of gcc. I get:
Darwin/PPC:
perl -E 'printf("%.2f"\, 6.685);' 6.69
Linux/i386:
perl -E 'printf("%.2f"\, 6.685);' 6.68
I suspect that the differences in the rounding is not Perl's problems -- but there are others on list who can speak better to that.
This difference is probably caused by the way x86 stores floating point values internal using 80 bits.
On the x86_64 floating point operation can also be done in 80 bits\, but the code generated by gcc uses the mmx registers that are 64 bits.
AFAIK\, most other architectures (ARM\, MIPS\, PPC\, SPARC) also represent doubles using 64 bits.
Looking at this thread\, how will this bug be closed? I think there are 3 options on the table to be taken.
1. Not a Perl bug\, close as rejected\, file a bug with your OS\, C compiler\, or CPU vendor\, add a couple sentences to perlport or perldata about "FP/NVs are OS and CPU specific" disclaimer. Con: Perl scripts aren't portable now.
2. Fix the makefiles on different Perl platforms to use the same FP behavior if supported by the CPU/compiler. Con: What to do about CPUs/compilers that aren't compliant? Deprecate and remove platforms? How would SPARCs\, Itaniums\, Power/PowerPC\, and ARMs behave with FP rounding in Perl?
3. Add a pure software FP library so FP on all Perl platforms is identical and reproducible perfectly. Con: Perl's abysmal scientific computing/multimedia performance will be even slower.
On Thu\, 04 Oct 2012\, bulk 88 via RT wrote:
Looking at this thread\, how will this bug be closed? I think there are 3 options on the table to be taken.
1. Not a Perl bug\, close as rejected\, file a bug with your OS\, C compiler\, or CPU vendor\, add a couple sentences to perlport or perldata about "FP/NVs are OS and CPU specific" disclaimer. Con: Perl scripts aren't portable now.
Maybe not a Perl bug\, but as Larry Wall once wrote: "The Golden Gate wasn't our fault either\, but we still put a bridge across it."
2. Fix the makefiles on different Perl platforms to use the same FP behavior if supported by the CPU/compiler. Con: What to do about CPUs/compilers that aren't compliant? Deprecate and remove platforms? How would SPARCs\, Itaniums\, Power/PowerPC\, and ARMs behave with FP rounding in Perl?
Perl should hide platform differences as much as possible\, and document the remaining ones in perlport.pod.
3. Add a pure software FP library so FP on all Perl platforms is identical and reproducible perfectly. Con: Perl's abysmal scientific computing/multimedia performance will be even slower.
I don't think this is useful. Doesn't Math::BigFloat already do this?
So *if* the problem turns out to be the floating point rounding mode used by the compiler/RTL\, then we should try to explicitly set a particular mode wherever we can.
Cheers\, -Jan
On Thu\, Oct 04\, 2012 at 10:20:33AM -0700\, bulk 88 via RT wrote:
2. Fix the makefiles on different Perl platforms to use the same FP behavior if supported by the CPU/compiler. Con: What to do about CPUs/compilers that aren't compliant? Deprecate and remove platforms? How would SPARCs\, Itaniums\, Power/PowerPC\, and ARMs behave with FP rounding in Perl?
And here it comes around again... btw the only platform afflicted with this problem is i386. And most compilers on i386 offered a flag like this a looooong time ago.
Date: Sat\, 22 Jan 2011 14:25:23 -0800 From: Greg Lindahl \greg@​blekko\.com To: Chip Salzenberg \rev\.chip@​gmail\.com Cc: p5p \perl5\-porters@​perl\.org Subject: Re: Being more careful with FP on gcc: Message-ID: \20110122222523\.GB14655@​bx9\.net
On Sat\, Jan 22\, 2011 at 08:39:13AM -0800\, Chip Salzenberg wrote:
After carefully considering http://blog.andreas.org/display?id=9 I believe we should add the flag "-fexcess-precision=standard" when compiling on gcc 4.5+. Any controversy here?
That flag is the right thing to do -- I'm surprised that it wasn't noticed earlier. It's not hard to write a little test in C so that we would know if other compilers need a similar switch\, too.
-- greg
On Thu\, 4 Oct 2012\, Greg Lindahl wrote:
On Thu\, Oct 04\, 2012 at 10:20:33AM -0700\, bulk 88 via RT wrote:
2. Fix the makefiles on different Perl platforms to use the same FP behavior if supported by the CPU/compiler. Con: What to do about CPUs/compilers that aren't compliant? Deprecate and remove platforms? How would SPARCs\, Itaniums\, Power/PowerPC\, and ARMs behave with FP rounding in Perl?
And here it comes around again... btw the only platform afflicted with this problem is i386. And most compilers on i386 offered a flag like this a looooong time ago.
Date: Sat\, 22 Jan 2011 14:25:23 -0800 From: Greg Lindahl \greg@​blekko\.com To: Chip Salzenberg \rev\.chip@​gmail\.com Cc: p5p \perl5\-porters@​perl\.org Subject: Re: Being more careful with FP on gcc: Message-ID: \20110122222523\.GB14655@​bx9\.net
On Sat\, Jan 22\, 2011 at 08:39:13AM -0800\, Chip Salzenberg wrote:
After carefully considering http://blog.andreas.org/display?id=9 I believe we should add the flag "-fexcess-precision=standard" when compiling on gcc 4.5+. Any controversy here?
That flag is the right thing to do -- I'm surprised that it wasn't noticed earlier. It's not hard to write a little test in C so that we would know if other compilers need a similar switch\, too.
Thank you for the reminder. I meant to look into this\, but life intervened last year\, and I have subsequently forgotten. I have taken this ticket to remind me about it.
If you still have a "little test in C" handy\, I would appreciate it.
For anyone interested: I would also welcome a pure perl test (to consider including in the test suite) to make sure we succeed in doing whatever it is we are trying to do.
Incidentally\, though gcc has had -ffloat-store for quite some time\, it
didn't quite do what we want. Based on the description in the fine
manual\, -fexcess-precision=standard looks like it might be a good choice\,
but it is only available in gcc-4.5 and later. gcc-4.5.2 was released in
December\, 2010\, which means it's not necessarily all that widespread yet.
For example\, Debian stable still uses 4.4.5. Unfortunately\, that's what
runs on the system I usually use to work on Configure\, so I have to sort
all that out first\, and it's unlikely to be quick.
And\, of course\, even if we do default to using that flag tomorrow\, I predict that the vagaries of floating point are such that we'll still be getting reports of floating point rounding issues for years to come :-).
-- Andy Dougherty doughera@lafayette.edu
On Fri\, Oct 05\, 2012 at 09:10:53AM -0400\, Andy Dougherty wrote:
If you still have a "little test in C" handy\, I would appreciate it.
This test works for me on my x86-64 desktop\, using -m32 to pretend to be i386. It fools the optimizer by passing a constant in on the command line.
I think what you want to use to fix this\, by the way\, is -mpc64\, which appeared in gcc 4.3\, if I read the release notes correctly. The manpage gives a scary-looking warning about using -mpc64 when linking with mathematical libraries\, which I suppose could be true\, but really\, ever since SSE appeared\, people stopped writing libraries that depended on 80-bit math being available.
Even better would be to stop compiling for the least common denominator and use -march and -mfpmath to force SSE instead of 387 math. After some experimenting I found that this did the trick:
gcc -O2 -m32 -march=pentium4 -mfpmath=sse test_fp80.c
This is a higher-level decision\, though\, I know most distros supporting i386 are not willing to go quite this far.
Finally\, if you really do want to use -fexcess-precision=standard\, you should also check out -fexcess-precision=fast.
Incidentally\, though gcc has had -ffloat-store for quite some time\, it didn't quite do what we want.
Right\, it inhibits many good optimizations\, you don't want that.
-- greg
/* * this program tests arithmetic to see if there is * excess precision visible in 64-bit floating point * computations. For example\, gcc on i386 targets defaults * to using 80387 80-bit precision math\, and sees * excess precision. gcc on x86-64 defaults to using * SSE math\, and does not see excess precision. * * gcc -O test_fp80.c * ./a.out 3 * */
#include \<stdio.h> #include \<stdlib.h>
int main( int argc\, char **argv ) { double one = 1.0; double three; double constant = 0.3333333333333333333333333; double residue; char *garbage;
if ( argc \< 2 ) { fprintf( stderr\, "No arg given. Give me a 3!\n" ); exit( 2 ); }
three = strtod( argv[1]\, &garbage );
residue = constant - one / three;
if ( residue > 1.e-17 || residue \< -1.e-17 ) { printf( "Saw excess precision.\n" ); exit( 1 ); } else { printf( "Did not see excess precision.\n" ); exit( 0 ); } }
This is the expected behavior of floats. We have a testcase here for which the closest 80-bit float is below the actual value\, and the closest 64-bit float is above it. Since the testcase is a 'tipping point' for rounding\, this results in slightly different behavior.
This is no different than any other platform difference in floating point. There are values that are exactly representable by 64 bit floats but not by 80 bit floats. Is it a bug that\, for example (x/2)*2==x is true on 32 bit platforms but false on 64 bit platforms for certain values of x?
We can "fix" this by loading a bignum library by default\, or by using the lowest common denominator - 64 bit double precision floats on all platforms? - but either of those options seems more disruptive. We already support using extended precision on platforms where it is available - is -Duselongdouble a bug?
perldoc perldata says\, (in a paragraph with some unrelated discussion on hex fp literals):
Notice that while most current platforms use the 64-bit IEEE 754 floating point\, not all do. Another potential source of (low-order) differences are the floating point rounding modes\, which can differ between CPUs\, operating systems\, and compilers\, and which Perl doesn't control.
perldoc perlnumber says:
Perl can internally represent numbers in 3 different ways: as native integers\, as **native floating point numbers**\, and as decimal strings. Decimal strings may have an exponential notation part\, as in "12.34e-56" . Native here means "a format supported by the C compiler which was used to build perl".
However\, "native" floats have a most fundamental restriction: they may represent only those numbers which have a relatively "short" representation when converted to a binary fraction. For example\, 0.9 cannot be represented by a native float\, since the binary fraction for 0.9 is infinite: binary0.1110011001100... with the sequence 1100 repeating again and again. In addition to this limitation\, the exponent of the binary number is also restricted when it is represented as a floating point number. On typical hardware\, floating point values can store numbers with up to 53 binary digits\, and with binary exponents between -1024 and 1024. In decimal representation this is close to 16 decimal digits and decimal exponents in the range of -304..304. The upshot of all this is that Perl cannot store a number like 12345678901234567 as a floating point number on such architectures without loss of information.
perldoc perlop says:
Floating-point numbers are only approximations to what a mathematician would call real numbers. There are infinitely more reals than floats\, so some corners must be cut. For example: printf "%.20g\n"\, 123456789123456789; # produces 123456789123456784 Testing for exact floating-point equality or inequality is not a good idea. Here's a (relatively expensive) work-around to compare whether two floating-point numbers are equal to a particular number of decimal places.
perldoc perlop and perlmodlib list some arbitrary precision libraries
I suggest that this ticket be closed rejected\, as Perl's use of native floats is documented\, as are the dangers of expecting a float to be exactly equal to the decimal value used to create it\, and both core and CPAN provide options for those who need arbitrary-precision arithmetic.
-- Respectfully\, Dan Collins
This is the expected behavior of floats. We have a testcase here for which the closest 80-bit float is below the actual value\, and the closest 64-bit float is above it. Since the testcase is a 'tipping point' for rounding\, this results in slightly different behavior.
This is no different than any other platform difference in floating point. There are values that are exactly representable by 64 bit floats but not by 80 bit floats. Is it a bug that\, for example (x/2)*2==x is true on 32 bit platforms but false on 64 bit platforms for certain values of x?
We can "fix" this by loading a bignum library by default\, or by using the lowest common denominator - 64 bit double precision floats on all platforms? - but either of those options seems more disruptive. We already support using extended precision on platforms where it is available - is -Duselongdouble a bug?
perldoc perldata says\, (in a paragraph with some unrelated discussion on hex fp literals):
Notice that while most current platforms use the 64-bit IEEE 754 floating point\, not all do. Another potential source of (low-order) differences are the floating point rounding modes\, which can differ between CPUs\, operating systems\, and compilers\, and which Perl doesn't control.
perldoc perlnumber says:
Perl can internally represent numbers in 3 different ways: as native integers\, as **native floating point numbers**\, and as decimal strings. Decimal strings may have an exponential notation part\, as in "12.34e-56" . Native here means "a format supported by the C compiler which was used to build perl".
However\, "native" floats have a most fundamental restriction: they may represent only those numbers which have a relatively "short" representation when converted to a binary fraction. For example\, 0.9 cannot be represented by a native float\, since the binary fraction for 0.9 is infinite: binary0.1110011001100... with the sequence 1100 repeating again and again. In addition to this limitation\, the exponent of the binary number is also restricted when it is represented as a floating point number. On typical hardware\, floating point values can store numbers with up to 53 binary digits\, and with binary exponents between -1024 and 1024. In decimal representation this is close to 16 decimal digits and decimal exponents in the range of -304..304. The upshot of all this is that Perl cannot store a number like 12345678901234567 as a floating point number on such architectures without loss of information.
perldoc perlop says:
Floating-point numbers are only approximations to what a mathematician would call real numbers. There are infinitely more reals than floats\, so some corners must be cut. For example: printf "%.20g\n"\, 123456789123456789; # produces 123456789123456784 Testing for exact floating-point equality or inequality is not a good idea. Here's a (relatively expensive) work-around to compare whether two floating-point numbers are equal to a particular number of decimal places.
perldoc perlop and perlmodlib list some arbitrary precision libraries
I suggest that this ticket be closed rejected\, as Perl's use of native floats is documented\, as are the dangers of expecting a float to be exactly equal to the decimal value used to create it\, and both core and CPAN provide options for those who need arbitrary-precision arithmetic.
-- Respectfully\, Dan Collins
@iabyn - Status changed from 'open' to 'rejected'
Migrated from rt.perl.org#115092 (status was 'rejected')
Searchable as RT115092$