develooper Front page | perl.perl5.porters | Postings from April 2007

Re: [perl #42260] power-of two differences in minus operation

Thread Previous | Thread Next
From:
Tels
Date:
April 9, 2007 12:15
Subject:
Re: [perl #42260] power-of two differences in minus operation
Message ID:
200704092116.21000@bloodgate.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Moin,

On Monday 09 April 2007 19:00:56 Andy Dougherty wrote:
> On Sat, 31 Mar 2007, jhh wrote:
> > # New Ticket Created by  jhh
> > # Please include the string:  [perl #42260]
> > # in the subject line of all future correspondence about this issue.
> > # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=42260 >
> >
> > The minus operator creates strange results for the given example.
>
> Here's a much shorter example that illustrates the same problem.
> What you are encountering is the finite resolution of perl's (and C's)
> floating point numbers.  If you really require 18-digit accuracy, then
> perl's built-in numbers are not the right tool.
>
> You are correct that the exact details of rounding off in the last
> bit have changed between 5.6 and 5.8, but in neither version should they
> have been considered reliable.
>
> > Using bignum or bigint does not change the results.
>
> That's odd.  You'll have to show us specifically what you're doing.
> It's probably best if you modify the program below and show what you
> expect and what you get.  BigInt should work.

When using "-Mbignum", the diff will be zero, but the printout of $c will be 
wrong since %0.f is used, which converts the BigInt to a normal floating 
point value before printing, thus losing bits:

	#!/usr/bin/perl -w
	my $mul = 2**32;
	my $a = 104712103;
	my $b = 50;
	my $c = 449735057880383538;
	# For these values, $mul * $a + $b == $c.  Thus $diff should be zero.
	my $diff = $c - ($a * $mul + $b);
	printf "Expected: $a $b 449735057880383538 0\n";
	printf "Got:      %.0f %.0f %.0f %.0f\n", $a, $b, $c, $diff;
	printf "\$c $c %0.f\n", $c;

Result (5.8.8 on 64bit, thus diff is 0 even without bignum):

	# perl acc.pl
	Expected: 104712103 50 449735057880383538 0
	Got:      104712103 50 449735057880383552 0
	$c 449735057880383538 449735057880383552
	# perl -Mbignum acc.pl
	Expected: 104712103 50 449735057880383538 0
	Got:      104712103 50 449735057880383552 0
	$c 449735057880383538 449735057880383552

I am not sure if printf("%0.f", $bignumber) should actually truncate the 
result, or just print it in all its glory. Can this even be achieved with 
overloading?

All the best,

Tels

- -- 
 Signed on Mon Apr  9 21:11:42 2007 with key 0x93B84C15.
 View my photo gallery: http://bloodgate.com/photos
 PGP key on http://bloodgate.com/tels.asc or per email.

 "The need for a Steam account to play HL2 is like having to login to MS
 Passport to play Minesweeper."

  -- Tels
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iQEVAwUBRhqtJHcLPEOTuEwVAQIJhQf7BPTehno/agg+Qzw1tQkdL/dXFKLuwXby
PLggxcjanVjn4q3w5rg+FiJURPONQAOHPPgR8i8aYMYnXHd+WfsK4raVi2AGw7LL
jKOhyLwQBywNGvWhrEn8LFvid69CKIkIBUorLuj4i0NaxFAhoC8tKg3/fFxt6z5u
woMwdeUuMfBPi8iwOW+5GlVvYpQSp19WdflSaQhjv5LBFV2MdtnpYNiqX41DpzNt
H3KmhF3gZyD5R5CJvLYeQj+OrVjAWSjJ/pUoevJBlLU6O9EB1ujx6HLK6lV13zaU
fryvoNSQQpdiqM2ggGreccvPjyd7paAIO3e003sh8E2/k/sjE/xOpA==
=+9+y
-----END PGP SIGNATURE-----

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About