Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

IEEE 754 double floats

6 views
Skip to first unread message

Adam Warner

unread,
Nov 15, 2004, 9:51:11 PM11/15/04
to perl6-i...@perl.org
Hi all,

I've taken a first look at Parrot and I'm very impressed. I'd like to
perform some micro-benchmarking of double floating point code. I have the
latest CVS version of parrot. I've compiled it upon Debian unstable x86
with the:

perl Configure.pl --floatval=double

option. Yet the Leibniz summation for PI <http://www.parrotcode.org/examples/>
still appears to be performing its calculations using single floats and
continues to print 3.141591.

What's the step I've overlooked?

Many thanks,
Adam

Brent 'Dax' Royal-Gordon

unread,
Nov 16, 2004, 12:45:28 AM11/16/04
to Adam Warner, perl6-i...@perl.org
Adam Warner <li...@consulting.net.nz> wrote:
> I've taken a first look at Parrot and I'm very impressed. I'd like to
> perform some micro-benchmarking of double floating point code. I have the
> latest CVS version of parrot. I've compiled it upon Debian unstable x86
> with the:
>
> perl Configure.pl --floatval=double
>
> option. Yet the Leibniz summation for PI <http://www.parrotcode.org/examples/>
> still appears to be performing its calculations using single floats and
> continues to print 3.141591.

Parrot usually uses double as its floating-point type. The problem is
probably with the precision of 'print N0'; try using the 'sprintf'
opcode and printing the resulting string instead.

--
Brent 'Dax' Royal-Gordon <br...@brentdax.com>
Perl and Parrot hacker

There is no cabal.

Adam Warner

unread,
Nov 16, 2004, 3:50:35 AM11/16/04
to perl6-i...@perl.org
Hi Brent 'Dax' Royal-Gordon,

>> option. Yet the Leibniz summation for PI <http://www.parrotcode.org/examples/>
>> still appears to be performing its calculations using single floats and
>> continues to print 3.141591.
>
> Parrot usually uses double as its floating-point type. The problem is
> probably with the precision of 'print N0'; try using the 'sprintf'
> opcode and printing the resulting string instead.

Many thanks for the tip!

.sub _main
set N1, 1
set N2, 1000000
set N3, 0
set N4, 0
set I1, 0
REDO: div N4, 1.0, N1
if I1, SUB
add N3, N4, N3
set I1, 1
branch END
SUB: sub N3, N3, N4
set I1, 0
END: add N1, 2
le N1, N2, REDO
DONE: mul N3, N3, 4.0

new P0, .PerlArray
set P0, 1
set P0[0], N3
sprintf S0, "PI is (very) approximately: %.20f\n", P0
print S0
end
.end

On a windows binary I downloaded the precision is indeed double (~16
decimal places). With my current Linux binary it's extreme (here's 60
decimal places):

PI is (very) approximately: 3.141590653589694692726652647252194583415985107421875000000000

This may be the long double version that I compiled :-)

Thanks again,
Adam

Adam Warner

unread,
Nov 16, 2004, 4:22:00 AM11/16/04
to perl6-i...@perl.org
> This may be the long double version that I compiled :-)

Note: I've rebuilt parrot-latest.tar.gz (I believe it was
2004-11-16_000000) at default settings on Debian unstable 2.6.8.1 i686
GNU/Linux. I'm still printing floats that appear to be 128-bit precision!

Regards,
Adam

Leopold Toetsch

unread,
Nov 16, 2004, 4:15:08 AM11/16/04
to Adam Warner, perl6-i...@perl.org
Adam Warner <li...@consulting.net.nz> wrote:

> On a windows binary I downloaded the precision is indeed double (~16
> decimal places). With my current Linux binary it's extreme (here's 60
> decimal places):

> PI is (very) approximately:
3.141590653589694692726652647252194583415985107421875000000000

^^^^^
3.141592653589793238462643383279502884197169399375105820974944

You might probably want to run more iterations ;) And you'll never get
60 digits out of long doubles.

> Thanks again,
> Adam

leo

Adam Warner

unread,
Nov 16, 2004, 7:13:21 AM11/16/04
to perl6-i...@perl.org
Hi Leopold Toetsch,

>> PI is (very) approximately:
> 3.141590653589694692726652647252194583415985107421875000000000
> ^^^^^
> 3.141592653589793238462643383279502884197169399375105820974944
>
> You might probably want to run more iterations ;) And you'll never get
> 60 digits out of long doubles.

I appreciate that Leopold. I thought the zeros indicated where the stored
value cuts off. But with 52 significant figures at ~3.3 bits per figure
that's about 172 bits, which indicates they would have to be 256 bit
floats when including the exponent (my mistake in calling them 128 bit)!

In other words sprintf is printing trailing garbage:

.sub _main
set N1, 2.0
set N2, 3.0
div N1, N1, N2


new P0, .PerlArray
set P0, 1

set P0[0], N1
sprintf S0, "%.60f\n", P0
print S0
end
.end

On the CVS version I compiled this prints:
0.666666666666666629659232512494781985878944396972656250000000

On this win32 release (running on a different machine):
http://www.jwcs.net/developers/perl/pow/download/pow-0.1.1-release.zip
parrot prints:
0.666666666666666630000000000000000000000000000000000000000000

Regards,
Adam

Leopold Toetsch

unread,
Nov 16, 2004, 7:38:48 AM11/16/04
to Adam Warner, perl6-i...@perl.org
Adam Warner <li...@consulting.net.nz> wrote:

> In other words sprintf is printing trailing garbage:

Well, the underlaying architecture is defining the precision of floats.
And due to the binary nature of the representation of floats they are
mostly just and inprecise approximation of a given float value and of
course only until a certain limit of digits.

All printed digits beyond that limit are just not defined,
implementation dependent, whatever - or garbage.

> Regards,
> Adam

leo

Bill Coffman

unread,
Nov 16, 2004, 11:38:50 AM11/16/04
to Adam Warner, perl6-i...@perl.org
Another way is to count the bits, as in the following:

.sub _main
N1 = 1
N2 = 0.5
I0 = 0
REPEAT:
I0 = I0 + 1
N2 = N2 / 2
N3 = N1 + N2
ne N1, N3, REPEAT

print I0
print " bits precision\n"
end
.end

0 new messages