Weirdness
Rafael Garcia-Suarez
rgarciasuarez at gmail.com
Mon Feb 25 17:21:13 GMT 2008
On 25/02/2008, Dan Rowles <d.rowles at outcometechnologies.com> wrote:
> Hello,
>
> I have encountered some weirdness with floating point numbers, and I was
> hoping for your collective wisdom on what to do next.
>
> I have two values that are being generated by some test code, and are
> being compared with the "is" method in Test::More. One is calculated
> from a database, the other is calculated via Statistics::Descriptive, in
> order to confirm that an SQL query is working properly.
>
> My code says:-
> is(sprintf('%.5f', $this), sprintf('%.5f', $that));
>
> The test fails, stating:-
> # Failed test 'max score is ok'
> # in t/reports/13health_change_per_procedure.t at line 241.
> # got: '4.74812'
> # expected: '4.74811'
>
> Fair enough - they are different. Printing out their values shows:-
> # THIS: '4.748115'
> # THAT: '4.748115'
>
> The numbers are identical when printed, but are rounded differently. So
> I used the "Dump" method in Devel::Peek to have a closer look at these
> numbers:-
>
> THIS: SV = PVNV(0xa2ac528) at 0xa1c3a6c
> REFCNT = 1
> FLAGS = (PADBUSY,PADMY,NOK,POK,pNOK,pPOK)
> IV = 0
> NV = 4.748115
> PV = 0xa2b36e8 "4.748115"\0
> CUR = 8
> LEN = 20
>
> THAT: SV = PVNV(0xa2ac4f8) at 0xa1c39e8
> REFCNT = 1
> FLAGS = (PADBUSY,PADMY,NOK,POK,pIOK,pNOK,pPOK)
> IV = 4
> NV = 4.748115
> PV = 0xa2f2da8 "4.748115"\0
> CUR = 8
> LEN = 36
>
> Finally, I attempted to dump out their raw representation using the
> following code:-
> unpack("B*", pack("d",$this));
>
> This produced:
> THIS: 1001001010010110110010101101101100010001111111100001001001000000
> THAT: 1001000010010110110010101101101100010001111111100001001001000000
> DIFF: ^
>
> These are two different numbers, and perl correctly says that they are
> different when I compare them, but it prints them out as exactly the
> same number.
>
> Now, I know very little about machine representations of floating point
> numbers, but I *guess* that this means that the numbers differ by too
> small an amount to print out, even though they do differ.
>
> So my question to you is, should I report this as a bug somewhere, or
> should I just ignore it as "floating point weirdness"?
perl's printf (and Devel::Peek) don't print every available digit for
floating point numbers, but use a default precision of whatever your
platform defines the C macro DBL_DIG to be (that's often 6 on the
average Linux system. In your case, that's 6 indeed)
If you want more decimals, you need to tell perl to do so, eg. with a
format "%.10f".
I guess that could be documented more accurately...
More information about the london.pm
mailing list