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

Floating Point Number Printing Bug #1174

Closed
p5pRT opened this issue Feb 13, 2000 · 6 comments
Closed

Floating Point Number Printing Bug #1174

p5pRT opened this issue Feb 13, 2000 · 6 comments

Comments

@p5pRT
Copy link

p5pRT commented Feb 13, 2000

Migrated from rt.perl.org#2143 (status was 'resolved')

Searchable as RT2143$

@p5pRT
Copy link
Author

p5pRT commented Feb 13, 2000

From pdh@best.com

Created by pdh@best.com

Hi,

This is an obscure bug. A number is reported as being precisely 25,
but when int() is applied, it is changed to 24. No doubt the number
is something like 24.99999999999 and print() is somehow falsely
reporting it as 25. (See below).

I've been using perl for years without ever really finding a bug, so
this is quite exciting!

Peter
pdh@​best.com

Case 1​: Works
perl -e 'print exp( (1 / 2) * log(625) ), "\n"'
25

Case 2​: Take integer part, doesn't work​:
perl -e 'print int(exp( (1 / 2) * log(625) )), "\n"'
24

Case 3​: Add small constant, works again​:
perl -e 'print int(exp( (1 / 2) * log(625) ) + .0000001), "\n"'
25

Perl Info


Site configuration information for perl 5.00404:

Configured by pdh at Sat Dec 25 13:02:06 PST 1999.

Summary of my perl5 (5.0 patchlevel 4 subversion 4) configuration:
  Platform:
    osname=netbsd, osvers=1.4.1, archname=i386-netbsd
    uname='netbsd natasha 1.4.1 netbsd 1.4.1 (generic) #0: thu dec 23 09:54:05 pst 1999 pdh@natasha:usrsrcsysarchi386compilegeneric i386 '
    hint=recommended, useposix=true, d_sigaction=define
    bincompat3=y useperlio=undef d_sfio=undef
  Compiler:
    cc='cc', optimize='-O2', gccversion=egcs-2.91.60 19981201 (egcs-1.1.1 release)
    cppflags='-I/usr/pkg/include'
    ccflags ='-I/usr/pkg/include'
    stdchar='char', d_stdstdio=undef, usevfork=true
    voidflags=15, castflags=0, d_casti32=define, d_castneg=define
    intsize=4, alignbytes=4, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='ld', ldflags =' -L/usr/pkg/lib'
    libpth=/usr/pkg/lib /usr/lib
    libs=-lm -lcrypt
    libc=/usr/lib/libc.so.12.40, so=so
    useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=define, ccdlflags='-Wl,-R/usr/pkg/lib  -Wl,-R/usr/pkg/lib/perl5/i386-netbsd/5.00404/CORE'
    cccdlflags='-DPIC -fPIC ', lddlflags='-Bforcearchive -Bshareable  -L/usr/pkg/lib'

Locally applied patches:
	


@INC for perl 5.00404:
	/usr/pkg/lib/perl5/i386-netbsd/5.00404
	/usr/pkg/lib/perl5
	/usr/pkg/lib/perl5/site_perl/i386-netbsd
	/usr/pkg/lib/perl5/site_perl
	.


Environment for perl 5.00404:
    HOME=/usr/home/pdh
    LANG (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/bin:/bin:/usr/pkg/bin:/usr/local/bin:/usr/home/pdh/bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/pkg/sbin:/usr/pkg/bin:/usr/X11R6/bin:/usr/local/sbin:/usr/local/bin
    PERL_BADLANG (unset)
    SHELL=/usr/pkg/bin/bash


@p5pRT
Copy link
Author

p5pRT commented Feb 13, 2000

From @tamias

On Sun, Feb 13, 2000 at 03​:50​:27PM -0800, Peter Hendrickson wrote​:

This is a bug report for perl from pdh@​best.com,
generated with the help of perlbug 1.20 running under perl 5.00404.

-----------------------------------------------------------------
[Please enter your report here]
Hi,

This is an obscure bug. A number is reported as being precisely 25,
but when int() is applied, it is changed to 24. No doubt the number
is something like 24.99999999999 and print() is somehow falsely
reporting it as 25. (See below).

I've been using perl for years without ever really finding a bug, so
this is quite exciting!

I'm afraid this bug is neither as obscure nor as exciting as you think.

perldoc -q decimal (or perldoc perlfaq4 with perl5.004_04)

=head2 Why am I getting long decimals (eg, 19.9499999999999) instead of the
numbers I should be getting (eg, 19.95)?

Ronald

@p5pRT
Copy link
Author

p5pRT commented Feb 14, 2000

From [Unknown Contact. See original ticket]

Created by pdh@best.com

Hi,

This is an obscure bug. A number is reported as being precisely 25,
but when int() is applied, it is changed to 24. No doubt the number
is something like 24.99999999999 and print() is somehow falsely
reporting it as 25. (See below).

I've been using perl for years without ever really finding a bug, so
this is quite exciting!

I'm afraid this bug is neither as obscure nor as exciting as you think.

perldoc -q decimal (or perldoc perlfaq4 with perl5.004_04)

=head2 Why am I getting long decimals (eg, 19.9499999999999) instead of the
numbers I should be getting (eg, 19.95)?

I believe you have misunderstood the bug. The problem is that I am
*not* getting a long decimal. That is, a number is reported by
print() to be "25", but when int() is applied you get 24.

If I was getting something like "24.9999999999999..." I would be happy
because that would make sense. It doesn't make sense to report "25"
if the number is going to behave like "24.9999999999999...".

Here's another symptom. This should not happen​:

perl -e 'print 10000000000000 * exp( (1 / 2) * log(625) ), "\n";'
250000000000000

perl -e 'print int(10000000000000 * exp( (1 / 2) * log(625)) ), "\n";'
249999999999999

Peter
pdh@​best.com

P.S. Here's the original bug report​:
--------------------------------------------------
From pdh Sun Feb 13 15​:50​:11 -0800 2000
From​: Peter Hendrickson <pdh@​best.com>
To​: perlbug@​perl.com
Subject​: Floating Point Number Printing Bug

This is a bug report for perl from pdh@​best.com,
generated with the help of perlbug 1.20 running under perl 5.00404.

-----------------------------------------------------------------
[Please enter your report here]
Hi,

This is an obscure bug. A number is reported as being precisely 25,
but when int() is applied, it is changed to 24. No doubt the number
is something like 24.99999999999 and print() is somehow falsely
reporting it as 25. (See below).

I've been using perl for years without ever really finding a bug, so
this is quite exciting!

Peter
pdh@​best.com

Case 1​: Works
perl -e 'print exp( (1 / 2) * log(625) ), "\n"'
25

Case 2​: Take integer part, doesn't work​:
perl -e 'print int(exp( (1 / 2) * log(625) )), "\n"'
24

Case 3​: Add small constant, works again​:
perl -e 'print int(exp( (1 / 2) * log(625) ) + .0000001), "\n"'
25

Perl Info


Site configuration information for perl 5.00404:

Configured by pdh at Sat Dec 25 13:02:06 PST 1999.

Summary of my perl5 (5.0 patchlevel 4 subversion 4) configuration:
  Platform:
    osname=netbsd, osvers=1.4.1, archname=i386-netbsd
    uname='netbsd natasha 1.4.1 netbsd 1.4.1 (generic) #0: thu dec 23 09:54:05 pst 1999 pdh@natasha:usrsrcsysarchi386compilegeneric i386 '
    hint=recommended, useposix=true, d_sigaction=define
    bincompat3=y useperlio=undef d_sfio=undef
  Compiler:
    cc='cc', optimize='-O2', gccversion=egcs-2.91.60 19981201 (egcs-1.1.1 release)
    cppflags='-I/usr/pkg/include'
    ccflags ='-I/usr/pkg/include'
    stdchar='char', d_stdstdio=undef, usevfork=true
    voidflags=15, castflags=0, d_casti32=define, d_castneg=define
    intsize=4, alignbytes=4, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='ld', ldflags =' -L/usr/pkg/lib'
    libpth=/usr/pkg/lib /usr/lib
    libs=-lm -lcrypt
    libc=/usr/lib/libc.so.12.40, so=so
    useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=define, ccdlflags='-Wl,-R/usr/pkg/lib  -Wl,-R/usr/pkg/lib/perl5/i386-netbsd/5.00404/CORE'
    cccdlflags='-DPIC -fPIC ', lddlflags='-Bforcearchive -Bshareable  -L/usr/pkg/lib'

Locally applied patches:
	


@INC for perl 5.00404:
	/usr/pkg/lib/perl5/i386-netbsd/5.00404
	/usr/pkg/lib/perl5
	/usr/pkg/lib/perl5/site_perl/i386-netbsd
	/usr/pkg/lib/perl5/site_perl
	.


Environment for perl 5.00404:
    HOME=/usr/home/pdh
    LANG (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/bin:/bin:/usr/pkg/bin:/usr/local/bin:/usr/home/pdh/bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/pkg/sbin:/usr/pkg/bin:/usr/X11R6/bin:/usr/local/sbin:/usr/local/bin
    PERL_BADLANG (unset)
    SHELL=/usr/pkg/bin/bash



@p5pRT
Copy link
Author

p5pRT commented Feb 14, 2000

From @tamias

On Mon, Feb 14, 2000 at 02​:03​:32PM -0800, Peter Hendrickson wrote​:

I'm afraid this bug is neither as obscure nor as exciting as you think.

perldoc -q decimal (or perldoc perlfaq4 with perl5.004_04)

=head2 Why am I getting long decimals (eg, 19.9499999999999) instead of the
numbers I should be getting (eg, 19.95)?

I believe you have misunderstood the bug. The problem is that I am
*not* getting a long decimal. That is, a number is reported by
print() to be "25", but when int() is applied you get 24.

If I was getting something like "24.9999999999999..." I would be happy
because that would make sense. It doesn't make sense to report "25"
if the number is going to behave like "24.9999999999999...".

It's all the same 'bug'. print() uses a format for printing floating point
numbers that rounds the number to a certain position past the decimal
point. (That position depends on your system and the version of Perl.)
See the documentation for $# in perlvar. (It's depecrated, but explains
how print works with floating point numbers.)

int(), on the other hand, does not round the number before truncating it.

Try replacing your print with printf "%.16f".

Ronald

@p5pRT
Copy link
Author

p5pRT commented Feb 15, 2000

From [Unknown Contact. See original ticket]

Peter Hendrickson <pdh@​best.com> wrote

From​: Ronald J Kimball <rjk@​linguist.dartmouth.edu>

I'm afraid this bug is neither as obscure nor as exciting as you think.

perldoc -q decimal (or perldoc perlfaq4 with perl5.004_04)

=head2 Why am I getting long decimals (eg, 19.9499999999999) instead of the
numbers I should be getting (eg, 19.95)?

I believe you have misunderstood the bug. The problem is that I am
*not* getting a long decimal. That is, a number is reported by
print() to be "25", but when int() is applied you get 24.

No. Ronald understands floating point very well. You have failed
to understand the import of the FAQ which he quoted. But you are
not alone, so in current versions(*) of Perl, the entry for int() has been
extended​:

% perldoc -f int
=item int EXPR

=item int

Returns the integer portion of EXPR. If EXPR is omitted, uses C<$_>.
You should not use this function for rounding​: one because it truncates
towards C<0>, and two because machine representations of floating point
numbers can sometimes produce counterintuitive results. For example,
C<int(-6.725/0.025)> produces -268 rather than the correct -269; that's
because it's really more like -268.99999999999994315658 instead. Usually,
the C<sprintf()>, C<printf()>, or the C<POSIX​::floor> and C<POSIX​::ceil>
functions will serve you better than will int().

(*) I note you are using a Perl version which is two and a half years
  out of date; you might wish to consider upgrading. The
  documentation isn't the only thing which has been improved.

Mike Guy

@p5pRT
Copy link
Author

p5pRT commented Feb 15, 2000

From @tamias

On Tue, Feb 15, 2000 at 06​:38​:37PM +0000, M.J.T. Guy wrote​:

Peter Hendrickson <pdh@​best.com> wrote

I believe you have misunderstood the bug. The problem is that I am
*not* getting a long decimal. That is, a number is reported by
print() to be "25", but when int() is applied you get 24.

No. Ronald understands floating point very well. You have failed
to understand the import of the FAQ which he quoted. But you are
not alone, so in current versions(*) of Perl, the entry for int() has been
extended​:

FYI for p5p​: Peter emailed me offlist acknowledging that he understands the
issue now.

Ronald

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