mismatch between Perl 5.6 and Perl 5.8 in printing high precision

mismatch between Perl 5.6 and Perl 5.8 in printing high precision

am 02.04.2008 12:21:45 von vivekanand.naik

printf("%.32g\n",0.99999999976716936);

Perl 5.6.1 output:
0.99999999976716936 --> GOOD

Perl 5.8.6 output:
0.99999999976716925 --> ERROR


Any reason for such mismatch ?
Please let me know how to avoid that or any alternative approach if
any.

Thanks
Vivek

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision values.

am 02.04.2008 13:02:44 von RedGrittyBrick

vivekanand.naik@gmail.com wrote:
> printf("%.32g\n",0.99999999976716936);
>
> Perl 5.6.1 output:
> 0.99999999976716936 --> GOOD
>
> Perl 5.8.6 output:
> 0.99999999976716925 --> ERROR
>
>
> Any reason for such mismatch ?
> Please let me know how to avoid that or any alternative approach if
> any.
>

print Math::BigFloat->new("0.99999999976716936")->bstr();


--
RGB

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision values.

am 02.04.2008 13:18:42 von Mirco Wahab

vivekanand.naik@gmail.com wrote:
> printf("%.32g\n",0.99999999976716936);
>
> Perl 5.6.1 output:
> 0.99999999976716936 --> GOOD
>
> Perl 5.8.6 output:
> 0.99999999976716925 --> ERROR
> Any reason for such mismatch ?
> Please let me know how to avoid that or any alternative approach if
> any.

This is in the interval from 1e-16 to 1e-15, which
is the accuracy of a IEEE 8 byte double in this
number range (52 bits for fraction). Seems to
be ok ==> 1 / (2^52).
The correct result (above) needs (imho) longer
than 8 byte doubles, like

perl -MMath::BigFloat -e'print Math::BigFloat->new("0.99999999976716936")->bstr()'


Regards

M.

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision

am 02.04.2008 15:46:46 von sisyphus359

On Apr 2, 9:21=A0pm, vivekanand.n...@gmail.com wrote:
> printf("%.32g\n",0.99999999976716936);
>
> Perl 5.6.1 output:
> 0.99999999976716936 =A0--> GOOD
>
> Perl 5.8.6 output:
> 0.99999999976716925 =A0--> ERROR
>
> Any reason for such mismatch ?

I believe it's a bug in perl 5.8 (which has been carried through to
perl 5.10):

C:\_32\pscrpt>perl -e "printf(\"%.32g\n\",0.99999999976716936);"
0.99999999976716925

C:\_32\pscrpt>perl -e "printf(\"%.32g\n\",9.9999999976716936e-1);"
0.99999999976716936

Since 0.99999999976716936 == 9.9999999976716936e-1, I can think of no
good reason that that those 2 one-liners should produce different
output - and I believe the first one liner produces an incorrect
result.

I'll submit a bug report about this - unless someone can convince me
that it's *not* a bug (or unless someone else wants to submit the
report).

Cheers,
Rob

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision values.

am 02.04.2008 16:25:57 von Mirco Wahab

sisyphus wrote:
> On Apr 2, 9:21 pm, vivekanand.n...@gmail.com wrote:
>> printf("%.32g\n",0.99999999976716936);
>> Perl 5.6.1 output:
>> 0.99999999976716936 --> GOOD
>> Perl 5.8.6 output:
>> 0.99999999976716925 --> ERROR
> I believe it's a bug in perl 5.8 (which has been carried through to
> perl 5.10):
> C:\_32\pscrpt>perl -e "printf(\"%.32g\n\",0.99999999976716936);"
> 0.99999999976716925
> C:\_32\pscrpt>perl -e "printf(\"%.32g\n\",9.9999999976716936e-1);"
> 0.99999999976716936
>
> Since 0.99999999976716936 == 9.9999999976716936e-1, I can think of no
> good reason that that those 2 one-liners should produce different
> output - and I believe the first one liner produces an incorrect
> result.
>
> I'll submit a bug report about this - unless someone can convince me
> that it's *not* a bug (or unless someone else wants to submit the
> report).

Seems to be dependend on the underlying C library
implementation. Consider the following program round.c:
----- [round.c] -----
#include "stdio.h"
int main() {
printf("0.99999999976716936\n");
printf("%.32g | %.36f\n", 0.99999999976716936, 0.99999999976716936);
printf("%.32g | %.36f (%s)\n",9.9999999976716936e-1,9.9999999976716936e-1,"sisyphu s");
return 0;
}
--------------------

Results:
=========
Linux/gcc: gcc-4.3 -o round round.c ; ./round

0.99999999976716936
0.99999999976716935634613037109375 | 0.999999999767169356346130371093750000
0.99999999976716935634613037109375 | 0.999999999767169356346130371093750000 (sisyphus)

WinXP/Visual-C++ 2005 & Visual C++6.0 (same results):

0.99999999976716936
0.99999999976716936 | 0.999999999767169360000000000000000000
0.99999999976716936 | 0.999999999767169360000000000000000000 (sisyphus)


WinXP/MinGW 3.4.2

0.99999999976716936
0.99999999976716936 | 0.999999999767169360000000000000000000
0.99999999976716936 | 0.999999999767169360000000000000000000 (sisyphus)


Regards

M.

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision values.

am 02.04.2008 17:41:53 von szr

vivekanand.naik@gmail.com wrote:
> printf("%.32g\n",0.99999999976716936);
>
> Perl 5.6.1 output:
> 0.99999999976716936 --> GOOD
>
> Perl 5.8.6 output:
> 0.99999999976716925 --> ERROR

I get:

$ perlall -e 'printf("%.32g\n",0.99999999976716936);'
0.99999999976716935997820764892019
0.99999999976716935997820764892019
0.9999999997671692453238279085781
0.9999999997671692453238279085781
0.99999999976716935634613037109375

--
szr

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision values.

am 02.04.2008 17:53:25 von szr

RedGrittyBrick wrote:
> vivekanand.naik@gmail.com wrote:
>> printf("%.32g\n",0.99999999976716936);
>>
>> Perl 5.6.1 output:
>> 0.99999999976716936 --> GOOD
>>
>> Perl 5.8.6 output:
>> 0.99999999976716925 --> ERROR
>>
>>
>> Any reason for such mismatch ?
>> Please let me know how to avoid that or any alternative approach if
>> any.
>>
>
> print Math::BigFloat->new("0.99999999976716936")->bstr();


The version of Math::BigFloat that shipped with 5.6.1, which the op
seems to need, doesn't seem to support ->bstr()

$ perlall -MMath::BigFloat -e 'print
Math::BigFloat->new("0.99999999976716936")->bstr(), "\n";'
0.99999999976716936
0.99999999976716936
0.99999999976716936
0.99999999976716936
Can't locate object method "bstr" via package "Math::BigFloat" (perhaps
you forgot to load "Math::BigFloat"?) at -e line 1.



Perhaps ->ffround(17) could be used instead?

$ perl5.6.1 -MMath::BigFloat -e 'print
Math::BigFloat->new("0.99999999976716936")->ffround(-17), "\n";'
+99999999976716936E-17

You could always update your Math::* modules if you must use 5.6.1,
else, it would better to just install a newer Perl :-)

--
szr

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision values.

am 02.04.2008 18:02:34 von szr

sisyphus wrote:
> On Apr 2, 9:21 pm, vivekanand.n...@gmail.com wrote:
>> printf("%.32g\n",0.99999999976716936);
>>
>> Perl 5.6.1 output:
>> 0.99999999976716936 --> GOOD
>>
>> Perl 5.8.6 output:
>> 0.99999999976716925 --> ERROR
>>
>> Any reason for such mismatch ?
>
> I believe it's a bug in perl 5.8 (which has been carried through to
> perl 5.10):
>
> C:\_32\pscrpt>perl -e "printf(\"%.32g\n\",0.99999999976716936);"
> 0.99999999976716925
>
> C:\_32\pscrpt>perl -e "printf(\"%.32g\n\",9.9999999976716936e-1);"
> 0.99999999976716936
>
> Since 0.99999999976716936 == 9.9999999976716936e-1, I can think of no
> good reason that that those 2 one-liners should produce different
> output - and I believe the first one liner produces an incorrect
> result.
>
> I'll submit a bug report about this - unless someone can convince me
> that it's *not* a bug (or unless someone else wants to submit the
> report).
>
> Cheers,
> Rob

Interesting, I get these values:

$ perlall -e 'printf("%.32g\n",99999999976716936e-1);'
9999999997671693.599609375
9999999997671693.599609375
9999999997671692
9999999997671692
9999999997671694

--
szr

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision values.

am 02.04.2008 18:05:59 von szr

sisyphus wrote:
> On Apr 2, 9:21 pm, vivekanand.n...@gmail.com wrote:
>> printf("%.32g\n",0.99999999976716936);
>>
>> Perl 5.6.1 output:
>> 0.99999999976716936 --> GOOD
>>
>> Perl 5.8.6 output:
>> 0.99999999976716925 --> ERROR
>>
>> Any reason for such mismatch ?
>
> I believe it's a bug in perl 5.8 (which has been carried through to
> perl 5.10):
>
> C:\_32\pscrpt>perl -e "printf(\"%.32g\n\",0.99999999976716936);"
> 0.99999999976716925
>
> C:\_32\pscrpt>perl -e "printf(\"%.32g\n\",9.9999999976716936e-1);"
> 0.99999999976716936
>
> Since 0.99999999976716936 == 9.9999999976716936e-1, I can think of no
> good reason that that those 2 one-liners should produce different
> output - and I believe the first one liner produces an incorrect
> result.
>
> I'll submit a bug report about this - unless someone can convince me
> that it's *not* a bug (or unless someone else wants to submit the
> report).
>
> Cheers,
> Rob

Please disregard my previous reply, I made a dump typo.

This is what I get:

$ perlall -e 'printf("%.32g\n",9.9999999976716936e-1);'
0.99999999976716935997820764892019
0.99999999976716935997820764892019
0.99999999976716935634613037109375
0.99999999976716935634613037109375
0.99999999976716935634613037109375

--
szr

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision

am 02.04.2008 21:58:34 von Ilya Zakharevich

[A complimentary Cc of this posting was sent to
sisyphus
], who wrote in article <28eff3d6-c1b4-4679-9838-38c295b4da66@i7g2000prf.googlegroups.com>:
> Since 0.99999999976716936 == 9.9999999976716936e-1

Why this would be so? At best, one is 0.99999999976716936, another is
9.9999999976716936/10. I know no axiom of FP arithmetic which would
make them equal...

(In principle, one could impose a condition on atof() that all strings
are first normalized IN DECIMAL to the e00 exponent, THEN translated
to binary. But given that, AFAIK, atof() is not documented to satisfy
ANY requirement, however reasonable, this is a pipe dream.)

[I have, on a backburner, some plans to make Perl use "the best"
string-to-FP-to-string conversions (so that a lot of verbiage can be
removed from perlnumber.pod). But my improve-perl plans do not get a
lot of timeslices recently.]

Yours,
Ilya

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision

am 03.04.2008 01:41:56 von sisyphus359

On Apr 3, 6:58=A0am, Ilya Zakharevich wrote:
> [A complimentary Cc of this posting was sent to
> sisyphus
> ], who wrote in article <28eff3d6-c1b4-4679-9838-38=
c295b4d...@i7g2000prf.googlegroups.com>:
>
> > Since 0.99999999976716936 =3D3D=3D3D 9.9999999976716936e-1
>
> Why this would be so? =A0At best, one is 0.99999999976716936, another is
> 9.9999999976716936/10. =A0I know no axiom of FP arithmetic which would
> make them equal...

Oh! ... ok. (I was thinking that perl should see the same mantissa in
both instances, and therefore store the same value.)

The other thing I note is that (with 52 bits of precision, plus the
implicit leading "1.") 0.99999999976716936 is represented in base 2
as:
1.1111111111111111111111111111111000000000000000000000e-1
And that converts back to 0.99999999976716936 (in base 10).

OTOH, 0.99999999976716925 is represented as:
1.1111111111111111111111111111110111111111111111111111e-1
And that converts back to 0.99999999976716925 (in base 10).

For my conversions, I'm using "round to nearest" mode - and I'm using
the mpfr C library (version 2.3.1) - which, according to its homepage
at http://www.mpfr.org/ provides "correct rounding" and "copies the
good ideas from the ANSI/IEEE-754 standard for double-precision
floating-point arithmetic (53-bit mantissa)". I've not yet had any
cause to take issue with those claims.

For me, (the recent versions of)perl are at odds with everything else
on my box in (apparently) insisting that 0.99999999976716936 has the
internal base 2 representation of:
1.1111111111111111111111111111110111111111111111111111e-1

Everything else uses an internal representation of
1.1111111111111111111111111111111000000000000000000000e-1.

Is that still not a perl bug ? (This FP stuff is just so damned
tricky, I never know what to think for sure :-)

Cheers,
Rob

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision

am 03.04.2008 02:08:59 von Ben Morrow

Quoth sisyphus :
>
> For me, (the recent versions of)perl are at odds with everything else
> on my box in (apparently) insisting that 0.99999999976716936 has the
> internal base 2 representation of:
> 1.1111111111111111111111111111110111111111111111111111e-1

Do you know how it gets to that? Is it not simply calling your atof?

> Everything else uses an internal representation of
> 1.1111111111111111111111111111111000000000000000000000e-1.
>
> Is that still not a perl bug ? (This FP stuff is just so damned
> tricky, I never know what to think for sure :-)

I think the stated position is 'perl provides no guarantees about
anything to do with FP'. If you wish to implement, test, and document
something more consistent, please feel free.... :)

Ben

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision

am 03.04.2008 03:30:28 von Ilya Zakharevich

[A complimentary Cc of this posting was sent to
sisyphus
], who wrote in article <9223ba3f-712a-42f6-9a3d-4041582ea604@b5g2000pri.googlegroups.com>:
> For me, (the recent versions of)perl are at odds with everything else
> on my box in (apparently) insisting that 0.99999999976716936 has the
> internal base 2 representation of:
> 1.1111111111111111111111111111110111111111111111111111e-1
>
> Everything else uses an internal representation of
> 1.1111111111111111111111111111111000000000000000000000e-1.
>
> Is that still not a perl bug ? (This FP stuff is just so damned
> tricky, I never know what to think for sure :-)

You may want to consult

perl -V:d_Gconvert

It might help you understand what happens...

Yours,
Ilya

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision

am 03.04.2008 04:09:19 von Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Ilya Zakharevich
], who wrote in article :
> > For me, (the recent versions of)perl are at odds with everything else
> > on my box in (apparently) insisting that 0.99999999976716936 has the
> > internal base 2 representation of:
> > 1.1111111111111111111111111111110111111111111111111111e-1
> >
> > Everything else uses an internal representation of
> > 1.1111111111111111111111111111111000000000000000000000e-1.
> >
> > Is that still not a perl bug ? (This FP stuff is just so damned
> > tricky, I never know what to think for sure :-)
>
> You may want to consult
>
> perl -V:d_Gconvert
>
> It might help you understand what happens...

Oups, it is THE OTHER direction! In fact, I do not know what Perl
uses to parse FP numbers. Let me check.... In 5.8.8:

#define Atof my_atof

which, essentially, calls Perl_my_atof2(), which OMG! calls a
home-brewed implementation! Shame on us! No wonder it behaves
fishy; coding string-to-num conversion is not for weaklings...

But before ringing the bell, please consider what is the *right*
answer. E.g.,

0.99999999976716936 * 2**75
= 37778931854161068825399.29174657778843648

The integer part is essentially

0b1111111111111111111111111111111100000000000000000000000001 00000001010111001

Perl behaves as if it were

0b11111111111111111111111111111110111111111111111111111...

The rest as if it were

0b11111111111111111111111111111111000000000000000000000...

So indeed, Perl's implemenation is extremely buggy (as anything
written by people who do not LIVE WITH FP would be)...

Hope this helps,
Ilya

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision

am 03.04.2008 06:33:21 von Ilya Zakharevich

[A complimentary Cc of this posting was sent to
sisyphus
], who wrote in article <9223ba3f-712a-42f6-9a3d-4041582ea604@b5g2000pri.googlegroups.com>:
> For me, (the recent versions of)perl are at odds with everything else
> on my box in (apparently) insisting that 0.99999999976716936 has the
> internal base 2 representation of:
> 1.1111111111111111111111111111110111111111111111111111e-1
>
> Everything else uses an internal representation of
> 1.1111111111111111111111111111111000000000000000000000e-1.

Yet another thought (that's just alias for Perl's printf):

pprintff .31g 0.99999999976716936
0.999999999767169245324

pprintff .31g 99999999976716936/100000000000000000
0.999999999767169245324

pprintff .31g 99999999976716936
99999999976716928

So it looks like whoever wrote Perl's Atof() thought (in their greate
wiseness) that one is allowed to translate the mantissa in 3
operations: convert the "integer mantissa" to an FP value, then
convert the corresponding 1000...000 to an FP value, then divide.

(The numerics people would immediately note that doing 3 operations
increases the maximal possible error 3 times, which is not allowed.
The trickyness of string-to-FP conversion is that it cannot be done
using just the precision of the FP primitives; one needs to get a
higher precision that this...)

Hope this helps,
Ilya

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision values.

am 03.04.2008 16:54:50 von Ted Zlatanov

On Thu, 3 Apr 2008 01:08:59 +0100 Ben Morrow wrote:

BM> I think the stated position is 'perl provides no guarantees about
BM> anything to do with FP'.

Position of who?

There's Math::BigFloat and Math::BigRat which are at least moderately
useful.

Ted

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision values.

am 03.04.2008 23:54:51 von Ben Morrow

Quoth Ted Zlatanov :
> On Thu, 3 Apr 2008 01:08:59 +0100 Ben Morrow wrote:
>
> BM> I think the stated position is 'perl provides no guarantees about
> BM> anything to do with FP'.
>
> Position of who?

Whom. :-)

Of p5p, but note that I don't speak for 'them' in any way, so I may be
mis-stating the case.

> There's Math::BigFloat and Math::BigRat which are at least moderately
> useful.

There are; there are also the bigint and bignum pragmata which make them
more useful still. I was talking about perl's handling of real platform
floats (NVs).

Ben

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision

am 04.04.2008 00:23:45 von Ilya Zakharevich

[A complimentary Cc of this posting was sent to
sisyphus
], who wrote in article <9223ba3f-712a-42f6-9a3d-4041582ea604@b5g2000pri.googlegroups.com>:
> > > Since 0.99999999976716936 == 9.9999999976716936e-1
> >
> > Why this would be so? At best, one is 0.99999999976716936, another is
> > 9.9999999976716936/10. I know no axiom of FP arithmetic which would
> > make them equal...
>
> Oh! ... ok. (I was thinking that perl should see the same mantissa in
> both instances, and therefore store the same value.)

Note that in other posts I flipped my position in this question.
According to the semantic in perlnumber.pod, a decimal string should
be considered as the REAL (as opposite to FP!) number exactly
representable by this decimal. When needed for its operation, Perl
has the right to convert it to the closest exactly representable FP
number.

In particular, in Perl one must have

0.99999999976716936 == 9.9999999976716936e-1

[As far as Perl was using CRT library routines for string-to-FP
conversion, there were an excuse for some deviations from this
semantic. However, since nowadays uses its own routine, no such
deviation may be allowed.]

Yours,
Ilya

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision values.

am 04.04.2008 17:45:41 von Ted Zlatanov

On Thu, 3 Apr 2008 22:54:51 +0100 Ben Morrow wrote:

BM> Quoth Ted Zlatanov :
>> On Thu, 3 Apr 2008 01:08:59 +0100 Ben Morrow wrote:
>>
BM> I think the stated position is 'perl provides no guarantees about
BM> anything to do with FP'.
>>
>> Position of who?

BM> Whom. :-)

Eh, if I remembered those grammar rules I'd have no room in my brain for
what $| does :)

BM> Of p5p, but note that I don't speak for 'them' in any way, so I may be
BM> mis-stating the case.

I'm curious if there are, in fact, some guarantees. For example, "on a
full moon, under the willow tree, while softly singing the songs of
distant Earth, adding two floats will, sometimes, give you a float that
is roughly equal to their sum." You know, spice up the docs a bit.

>> There's Math::BigFloat and Math::BigRat which are at least moderately
>> useful.

BM> There are; there are also the bigint and bignum pragmata which make them
BM> more useful still. I was talking about perl's handling of real platform
BM> floats (NVs).

Right, but big* is a FP interface that's quite useful, and should at
least be mentioned when people complain about platform floats. Then
those same people can complain about big* performance and Intel/AMD can
sell them faster processors. Everybody wins.

Ted

Re: mismatch between Perl 5.6 and Perl 5.8 in printing high precision

am 07.04.2008 15:12:15 von sisyphus359

On Apr 3, 10:08=A0am, Ben Morrow wrote:


> Is it not simply calling your atof?

I don't think so - and I see, further down, that Ilya has reported it
calls a "home-brewed" implementation.

I tried out ActiveState's builds of perl 5.6.1, 5.8.8 and 5.10.0 - all
three of which use the same underlying C library (Visual Studio 6.0).

Again, with their 5.6 build I get:

C:\_32\pscrpt>perl -e "printf(\"%.32g\n\",9.9999999976716936e-1);"
0.99999999976716936

Yet, with their builds of 5.8 and 5.10 I get:

C:\_32\pscrpt>perl -e "printf(\"%.32g\n\",9.9999999976716936e-1);"
0.99999999976716925

I think that rules out differences in the C library as the cause of
the discrepancy.

As regards atof() itself, the following C program outputs
0.99999999976716936:

int main( void )
{
double x;

x =3D atof("0.99999999976716936");
printf( "%.17f\n", x );

}

Cheers,
Rob