# New Ticket Created by "Marie Vivian Wong Tzu Yenn" # Please include the string: [perl #22725] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=22725 >
Hi there,
I'm new to perl and was writing a small program. Found something funny. When I try to add this particular sequence of numbers (0.4+0.3+0.2+0.1), it does not add up to one. (falls to the else loop). The version of perl compiler I am using is perl 5.6.1 on windows and solaris
If I change these numbers to like 0.25+0.5+0.25 OR 0.9+0.1 etc then no problem.
Here is the code snippet:
************************* use strict; use warnings;
my $tmp = 0.4+0.3+0.2+0.1; if ($tmp == 1) { print "Equals one", "\n";
-----Original Message----- From: Marie Vivian Wong Tzu Yenn [mailto:perlbug-follo...@perl.org] Sent: 18 June 2003 04:26 To: perl5-port...@perl.org Subject: [perl #22725] is this a bug?
# New Ticket Created by "Marie Vivian Wong Tzu Yenn" # Please include the string: [perl #22725] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=22725 >
Hi there,
I'm new to perl and was writing a small program. Found something funny. When I try to add this particular sequence of numbers (0.4+0.3+0.2+0.1), it does not add up to one. (falls to the else loop). The version of perl compiler I am using is perl 5.6.1 on windows and solaris
If I change these numbers to like 0.25+0.5+0.25 OR 0.9+0.1 etc then no problem.
Here is the code snippet:
************************* use strict; use warnings;
my $tmp = 0.4+0.3+0.2+0.1; if ($tmp == 1) { print "Equals one", "\n"; } else { print "Not equal to one", "\n"; } exit;
------------------------------------------------------------------- This e-mail and any attachments may contain confidential and/or privileged material; it is for the intended addressee(s) only. If you are not a named addressee, you must not use, retain or disclose such information.
NPL Management Ltd cannot guarantee that the e-mail or any attachments are free from viruses.
NPL Management Ltd. Registered in England and Wales. No: 2937881 Registered Office: Teddington, Middlesex, United Kingdom TW11 0LW. -------------------------------------------------------------------
> of numbers (0.4+0.3+0.2+0.1), it does not add up to one. > (falls to the else loop). ... > If I change these numbers to like 0.25+0.5+0.25 OR 0.9+0.1 > etc then no problem.
At first I thought this was a classic example of rounding problems. Assuming that the binary representation of that sequence when summed doesnt actually equal 1. As it would appear can be seen here:
I wrote: > see C<perldoc -f decimal> for a full explanation.
I meant: perldoc -q decimal
Robin
------------------------------------------------------------------- This e-mail and any attachments may contain confidential and/or privileged material; it is for the intended addressee(s) only. If you are not a named addressee, you must not use, retain or disclose such information.
NPL Management Ltd cannot guarantee that the e-mail or any attachments are free from viruses.
NPL Management Ltd. Registered in England and Wales. No: 2937881 Registered Office: Teddington, Middlesex, United Kingdom TW11 0LW. -------------------------------------------------------------------
As you can see, initializing $b to zero and adding 1e-16 for 100000 times can be done quite exact in IEEE math. It's because the numbers are all just about the same magnitude. It does not matter if you're dealing with numbers between 1 and 1000 or between 1e-100 and 1e-103. But adding 1 and 1e-100 is impossible.
That's what the second example shows: initializing $b to one and adding 1e-16 for 100000 times has no effect at all. Just because 1.0000000000000001 cannot be represented by a double precision float.
> And thanks for the follow up, I appreciate it.
> BTW, the above makes me think that its safer to sum floats inorder. Would this be correct?
Although I'm not an expert (so don't blame me if I'm wrong ;-) I'd say that adding floats should be more precise when you're doing it in ascending order of the absolute values.
> D:\Development>perl -e "print 0.4+0.3+0.2+0.1 == 1 ? 'Equals' : > 'NotEquals'" > NotEquals > Ill leave it up to somebody else to determine if it is in fact a bug, > and/or what the cause of the discrepancy between the outputs.
> Here's a patch for the bug: > ./perl -we "print 0.4+0.3+0.2+0.1 == 1 ? 'Equals' : 'NotEquals'" > Comparing equality of floating point values at -e line 1. > NotEquals
On Wed, Jun 18, 2003 at 04:25:45PM +0000, Ton Hospel wrote: > In article <18286.193.134.254.145.1055950103.squir...@wesley.pjcj.net>, > "Paul Johnson" <p...@pjcj.net> writes: > > Orton, Yves said:
Marie Vivian Wong Tzu Yenn <perl5-port...@perl.org> writes:
># New Ticket Created by "Marie Vivian Wong Tzu Yenn" Please include the ># string: [perl #22725] in the subject line of all future correspondence about ># this issue. <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=22725 >
>Hi there,
>I'm new to perl and was writing a small program. Found something funny. When I >try to add this particular sequence of numbers (0.4+0.3+0.2+0.1), it does not >add up to one. (falls to the else loop). The version of perl compiler I am >using is perl 5.6.1 on windows and solaris
This isn't a perl problem it is a generic floating point problem common to all computers and languages.
The problem is that just as you cannot represent 1/6 or 1/3 as an exact decimal form, computers cannot represent 0.1 (1/10) as an exact binary form. So this fails for same reason 0.333 + 0.333 + 0.333 != 1
>If I change these numbers to like 0.25+0.5+0.25 OR 0.9+0.1 etc then no >problem.
0.25 and 0.5 are exact in binary. 0.9 and 0.1 are like 0.667 + 0.333 and happen to work.