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

printf %.20g value different from %.20f value #14062

Open
p5pRT opened this issue Sep 1, 2014 · 10 comments
Open

printf %.20g value different from %.20f value #14062

p5pRT opened this issue Sep 1, 2014 · 10 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 1, 2014

Migrated from rt.perl.org#122672 (status was 'open')

Searchable as RT122672$

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2014

From dmi@questrel.com

Created by dmi@questrel.com

perl -e 'printf"%.20f\n%.20g\n",(-3895.3125*-3341.25*8231)x2'
107128217302.73437500000000000000
107128217302.73438

should be identical except for trailing 0's
(as it was under perl 5.16.2 )
perl -e 'printf"%.20f\n%.20g\n",(-3895.3125*-3341.25*8231)x2'
107128217302.73437500000000000000
107128217302.734375

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl 5.16.3:

Configured by ActiveState at Mon Apr 14 14:52:33 PDT 2014.

Summary of my perl5 (revision 5 version 16 subversion 3) configuration:
   
  Platform:
    osname=linux, osvers=2.6.11-1.1369_fc4, archname=x86_64-linux-thread-multi
    uname='linux perl-linux64-vm 2.6.11-1.1369_fc4 #1 thu jun 2 22:56:33 edt 2005 x86_64 x86_64 x86_64 gnulinux '
    config_args='-ders -Dcc=gcc -Dusethreads -Duseithreads -Uinstallusrbinperl -Ulocincpth= -Uloclibpth= -Duse64bitall -Dlibpth=/lib64 /usr/lib64 /usr/local/lib64 -Accflags=-DUSE_SITECUSTOMIZE -Duselargefiles -Accflags=-DPERL_RELOCATABLE_INCPUSH -Accflags=-fno-merge-constants -Dprefix=/opt/ActivePerl-5.16 -Dprivlib=/opt/ActivePerl-5.16/lib -Darchlib=/opt/ActivePerl-5.16/lib -Dsiteprefix=/opt/ActivePerl-5.16/site -Dsitelib=/opt/ActivePerl-5.16/site/lib -Dsitearch=/opt/ActivePerl-5.16/site/lib -Dsed=/bin/sed -Duseshrplib -Dcf_by=ActiveState -Dcf_email=support@ActiveState.com'
    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 -DUSE_SITECUSTOMIZE -DPERL_RELOCATABLE_INCPUSH -fno-merge-constants -fno-strict-aliasing -pipe -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DUSE_SITECUSTOMIZE -DPERL_RELOCATABLE_INCPUSH -fno-merge-constants -fno-strict-aliasing -pipe'
    ccversion='', gccversion='4.0.0 20050519 (Red Hat 4.0.0-8)', 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 =''
    libpth=/lib64 /usr/lib64 /usr/local/lib64
    libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=/lib/libc-2.3.5.so, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.3.5'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/opt/ActivePerl-5.16/lib/CORE'
    cccdlflags='-fPIC', lddlflags='-shared -O2'

Locally applied patches:
    ACTIVEPERL_LOCAL_PATCHES_ENTRY


@INC for perl 5.16.3:
    /opt/ActivePerl-5.16/site/lib
    /opt/ActivePerl-5.16/lib
    .


Environment for perl 5.16.3:
    HOME=/home/dmi
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH=/home/dmi/workspace/lzLabs/trunk/lz_common/lib:/home/dmi/workspace/lzLabs/trunk/lz_rdb/lz_tree/lib:/home/dmi/workspace/lzLabs/trunk/lz_rdb/lz_SQPr/lib:/home/dmi/workspace/lzLabs/trunk/lz_log/lib:/home/dmi/workspace/lzLabs/trunk/lz_cfg/lib:/home/dmi/workspace/lzLabs/trunk/lz_json/lib
    LOGDIR (unset)
    PATH=/opt/ActivePerl-5.16/site/bin:/opt/ActivePerl-5.16/bin:/usr/lib64/qt-3.3/bin:/opt/apache-maven-3.2.2/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/share/cassandra/bin
    PERLDOC_PAGER=less -isXer
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2014

From @jkeenan

On Sun Aug 31 21​:32​:57 2014, dmi wrote​:

This is a bug report for perl from dmi@​questrel.com,
generated with the help of perlbug 1.39 running under perl 5.16.3.

-----------------------------------------------------------------
[Please describe your issue here]

perl -e 'printf"%.20f\n%.20g\n",(-3895.3125*-3341.25*8231)x2'
107128217302.73437500000000000000
107128217302.73438

should be identical except for trailing 0's
(as it was under perl 5.16.2 )
perl -e 'printf"%.20f\n%.20g\n",(-3895.3125*-3341.25*8231)x2'
107128217302.73437500000000000000
107128217302.734375

I don't have perl-5.16.2 available, so I cannot speak to any differences between 5.16.2 and 5.16.3.

However, using perlbrew to switch among the final or most recent sub-versions of the last 4 annual releases, I get the same output in each​:

#####
$ perlbrew switch perl-5.14.4
$ perl -e 'printf"%.20f\n%.20g\n",(-3895.3125*-3341.25*8231)x2'
107128217302.73437500000000000000
107128217302.73438

$ perlbrew switch perl-5.16.3
$ perl -e 'printf"%.20f\n%.20g\n",(-3895.3125*-3341.25*8231)x2'
107128217302.73437500000000000000
107128217302.73438

$ perlbrew switch perl-5.18.2
$ perl -e 'printf"%.20f\n%.20g\n",(-3895.3125*-3341.25*8231)x2'
107128217302.73437500000000000000
107128217302.73438

$ perlbrew switch perl-5.20.0
$ perl -e 'printf"%.20f\n%.20g\n",(-3895.3125*-3341.25*8231)x2'
107128217302.73437500000000000000
107128217302.73438
#####

So I cannot reproduce the bug.

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2014

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

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2014

From @jkeenan

On Mon Sep 01 05​:56​:23 2014, jkeenan wrote​:

On Sun Aug 31 21​:32​:57 2014, dmi wrote​:

This is a bug report for perl from dmi@​questrel.com,
generated with the help of perlbug 1.39 running under perl 5.16.3.

-----------------------------------------------------------------
[Please describe your issue here]

perl -e 'printf"%.20f\n%.20g\n",(-3895.3125*-3341.25*8231)x2'
107128217302.73437500000000000000
107128217302.73438

should be identical except for trailing 0's
(as it was under perl 5.16.2 )
perl -e 'printf"%.20f\n%.20g\n",(-3895.3125*-3341.25*8231)x2'
107128217302.73437500000000000000
107128217302.734375

I don't have perl-5.16.2 available, so I cannot speak to any
differences between 5.16.2 and 5.16.3.

However, using perlbrew to switch among the final or most recent sub-
versions of the last 4 annual releases, I get the same output in each​:

#####
$ perlbrew switch perl-5.14.4
$ perl -e 'printf"%.20f\n%.20g\n",(-3895.3125*-3341.25*8231)x2'
107128217302.73437500000000000000
107128217302.73438

$ perlbrew switch perl-5.16.3
$ perl -e 'printf"%.20f\n%.20g\n",(-3895.3125*-3341.25*8231)x2'
107128217302.73437500000000000000
107128217302.73438

$ perlbrew switch perl-5.18.2
$ perl -e 'printf"%.20f\n%.20g\n",(-3895.3125*-3341.25*8231)x2'
107128217302.73437500000000000000
107128217302.73438

$ perlbrew switch perl-5.20.0
$ perl -e 'printf"%.20f\n%.20g\n",(-3895.3125*-3341.25*8231)x2'
107128217302.73437500000000000000
107128217302.73438
#####

More data.

Tux alerted me to the fact that it is possible on the Dromedary server to run a given Perl program with almost any released version of Perl 5 and compare results.

I did so. Here is an excerpt from those results (attached in gzipped file), focusing on 3 different builds of perl-5.20.0, all built on the same machine.

#####
=== base/cperl5.20.0 5.020000 i686-linux-64int-ld
107128217302.73437500000000000000
107128217302.734375
=== base/perl5.20.0 5.020000 i686-linux-64int
107128217302.73437500000000000000
107128217302.73438
=== base/tperl5.20.0 5.020000 i686-linux-thread-multi-64int-ld
107128217302.73437500000000000000
107128217302.734375
#####

And here are the runs for perl-5.16.2 and perl-5.16.3 on the same machine​:

#####
=== base/perl5.16.2 5.016002 i686-linux-64int
107128217302.73437500000000000000
107128217302.73438
=== base/tperl5.16.2 5.016002 i686-linux-thread-multi-64int-ld
107128217302.73437500000000000000
107128217302.734375
=== base/cperl5.16.3 5.016003 i686-linux-64int-ld
107128217302.73437500000000000000
107128217302.734375
=== base/perl5.16.3 5.016003 i686-linux-64int
107128217302.73437500000000000000
107128217302.73438
=== base/tperl5.16.3 5.016003 i686-linux-thread-multi-64int-ld
107128217302.73437500000000000000
107128217302.734375
#####

So my *preliminary* observation is that there are likely to be small differences in the output of those two different 'printf' formats for a given release of perl depending on how you build that release.

Bug or feature? Discuss (but let's not get dogmatic).

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2014

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2014

From @jhi

On Monday-201409-01, 9​:55, James E Keenan via RT wrote​:

Bug or feature? Discuss (but let's not get dogmatic).

Feature, for now... as seen on the inf/nan thread, this is what we have
promised (well, documented), and what we get by relying on the fp
printing of the underlying platform.

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2014

From @ikegami

All the builds with "ld" give 107128217302.734375
All the builds without "ld" give 107128217302.73438

What's "ld"?

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2014

From @jhi

On Monday-201409-01, 16​:52, Eric Brine wrote​:

All the builds with "ld" give 107128217302.734375
All the builds without "ld" give 107128217302.73438

What's "ld"?

"long double". Which may mean many things. Sometimes it is == double.
Often it is the x86 80-bit extended precision (64 bits of mantissa, as
opposed to 53 in the usual double).

@p5pRT
Copy link
Author

p5pRT commented Sep 2, 2014

From @sisyphus

-----Original Message-----
From​: Jarkko Hietaniemi
Sent​: Tuesday, September 02, 2014 7​:06 AM
To​: Eric Brine ; perlbug-followup
Cc​: perl5 porters
Subject​: Re​: [perl #122672] printf %.20g value different from %.20f value

On Monday-201409-01, 16​:52, Eric Brine wrote​:

All the builds with "ld" give 107128217302.734375
All the builds without "ld" give 107128217302.73438

What's "ld"?

"long double". Which may mean many things. Sometimes it is == double.
Often it is the x86 80-bit extended precision (64 bits of mantissa, as
opposed to 53 in the usual double).

@p5pRT
Copy link
Author

p5pRT commented Sep 2, 2014

From @sisyphus

... and now for the message I was trying to send​:

-----Original Message-----
From​: Jarkko Hietaniemi
Sent​: Tuesday, September 02, 2014 12​:00 AM
To​: perlbug-followup@​perl.org
Cc​: perl5-porters@​perl.org
Subject​: Re​: [perl #122672] printf %.20g value different from %.20f value

On Monday-201409-01, 9​:55, James E Keenan via RT wrote​:

Bug or feature? Discuss (but let's not get dogmatic).

Feature, for now... as seen on the inf/nan thread, this is what we have
promised (well, documented), and what we get by relying on the fp printing
of the underlying platform.

It looks like a bug to me.
Unless there's some modifying aspect of "%g" formatting of which I'm
unaware, then "107128217302.734375" is the correct "%.20g" output for the
value under discussion - irrespective of whether that value is held within
a 53-bit double or a long double of precision >= 53.
(Note that 107128217302.734375 is expressed precisely in only 43 bits.)

This bug is *almost* excusable when the NV has 53 bits of precision - in
that 107128217302.73438 has exactly the same 53-bit representation as
107128217302.734375. But that's really no excuse, especially given that both
the %.20f and %.20e formatting of 107128217302.734375 function accurately
and correctly.

The sprintf docs say​:
%g a floating-point number, in %e or %f notation

but that documentation is wrong wrt 107128217302.734375 when the NV has 53
bits of precision.

Cheers,
Rob

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

2 participants