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
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.
>> 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
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
> 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
>> 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
> 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
.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