Skip Menu |
 

This queue is for tickets about the bignum CPAN distribution.

Report information
The Basics
Id: 18025
Status: resolved
Worked: 1.7 hours (100 min)
Priority: 0/
Queue: bignum

People
Owner: TELS [...] cpan.org
Requestors: martin [...] snowplow.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.17
Fixed in: (no value)



Subject: bignum/bigrat can lead to a number that is both 1 and 0
Download (untitled) / with headers
text/plain 1.2k
The following test code, when run on the stock cygwin build of perl 5.8.7, fails. Specifically, the value $ev prints as "1", but so does the value 1-$ev. #!perl use strict; use warnings; use Test::More tests => 4; use bignum; my $lnev = -7 / (10**17); my $ev=exp($lnev); is( sprintf('%0.5f',$ev) , '1.00000', '($ev) is approx. 1' ); is( sprintf('%0.5f',1-$ev) , '0.00000', '(1-$ev) is approx. 0' ); is( sprintf('%0.5f',1-"$ev") , '0.00000', '(1-"$ev") is approx. 0' ); cmp_ok( $ev, '!=', 0, '$ev should not equal 0'); __END__ Note that on my copy of 5.8.7, tests 2 and 4 fail. I have it on good authority that on perl 5.8.6, test 4 succeeds, though test 2 still fails. I _think_ it has something to do with the magic bignum applies to the exp function, rather than any magic being applied to constants since the following code properly prints 0: #!perl use Math::BigFloat; print ((new Math::BigFloat("1")) - exp(new Math::BigFloat("-7")/ (new Math::BigFloat("10")**(new Math::BigFloat("17"))))); __END__ But this code prints "1"; the only difference is "use bignum": #!perl use bignum; use Math::BigFloat; print ((new Math::BigFloat("1")) - exp(new Math::BigFloat("-7")/ (new Math::BigFloat("10")**(new Math::BigFloat("17"))))); __END__
From: nospam-abuse [...] bloodgate.com
Download (untitled) / with headers
text/plain 1.6k
On Mon Mar 06 21:05:32 2006, guest wrote: Show quoted text
> The following test code, when run on the stock cygwin build of perl > 5.8.7, fails. Specifically, the value $ev prints as "1", but so does > the value 1-$ev. > > #!perl > use strict; > use warnings; > use Test::More tests => 4; > use bignum; > > my $lnev = -7 / (10**17); > my $ev=exp($lnev); > > is( sprintf('%0.5f',$ev) , '1.00000', '($ev) is approx. 1' ); > is( sprintf('%0.5f',1-$ev) , '0.00000', '(1-$ev) is approx. 0' ); > is( sprintf('%0.5f',1-"$ev") , '0.00000', '(1-"$ev") is approx. 0' ); > > cmp_ok( $ev, '!=', 0, '$ev should not equal 0'); > __END__ > > Note that on my copy of 5.8.7, tests 2 and 4 fail. I have it on good > authority that on perl 5.8.6, test 4 succeeds, though test 2 still fails.
This is very wierd, I have now spent some time trying to figure out why $ev can be both 0 and 1 at the same time, but have no clue yet. On Perl 5.8.8, test 2 fails and test 4 passes, btw. Show quoted text
> I _think_ it has something to do with the magic bignum applies to the > exp function, rather than any magic being applied to constants since the > following code properly prints 0: > > #!perl > use Math::BigFloat; > print ((new Math::BigFloat("1")) - > exp(new Math::BigFloat("-7")/ > (new Math::BigFloat("10")**(new Math::BigFloat("17"))))); > __END__ > > But this code prints "1"; the only difference is "use bignum": > > #!perl > use bignum; > use Math::BigFloat; > print ((new Math::BigFloat("1")) - > exp(new Math::BigFloat("-7")/ > (new Math::BigFloat("10")**(new Math::BigFloat("17"))))); > __END__
I have no idea. Best wishes, Tels
Download (untitled) / with headers
text/plain 1.6k
On Sat Jan 27 06:59:44 2007, TELS wrote: Show quoted text
> On Mon Mar 06 21:05:32 2006, guest wrote:
> > The following test code, when run on the stock cygwin build of perl > > 5.8.7, fails. Specifically, the value $ev prints as "1", but so does
Okay, the issue boils down to sometimes int(1.0) == 0 :( Since the value exp() returns results in int($ev) == 0, the constructed bigint number is wrong. This looks like a perl bug to me, so I posted a question to p5p about this. Here is a testscript showing it doesn't have to do anything with BigInt: #!perl use strict; use warnings; use Test::More tests => 6; my $lnev = -7 / (10**17); my $ev=exp($lnev); my $nv = 1.0; use Devel::Peek; print Dump($ev); print Dump($nv); is( $ev, '1', '$ev == 1'); is( sprintf('%0.15f',$ev) , '1.000000000000000', '($ev) is approx. 1' ); is( int($ev), '1', 'int($ev) == 1'); is( $nv, '1', '$nv == 1'); is( sprintf('%0.15f',$nv) , '1.000000000000000', '($nv) is approx. 1' ); is( int($nv), '1', 'int($nv) == 1'); exit; Output: 1..6 SV = NV(0x682f70) at 0x76eaa0 REFCNT = 1 FLAGS = (PADBUSY,PADMY,NOK,pNOK) NV = 1 SV = NV(0x682f78) at 0x76ea90 REFCNT = 1 FLAGS = (PADBUSY,PADMY,NOK,pNOK) NV = 1 ok 1 - $ev == 1 ok 2 - ($ev) is approx. 1 not ok 3 - int($ev) == 1 # Failed test 'int($ev) == 1' # in fail.pl at line 16. # got: '0' # expected: '1' ok 4 - $nv == 1 ok 5 - ($nv) is approx. 1 ok 6 - int($nv) == 1 # Looks like you failed 1 test of 6 I am cnsidering closing this bug as there is nothing I can do inside bignum/bigrat to detect this sort of problem (if int() doesn't work correctly, well, then my code can't work correcty). Sorry! Thanx a lot for your bug report!
CC: bug-bignum [...] rt.cpan.org
Subject: Re: [rt.cpan.org #18025] bignum/bigrat can lead to a number that is both 1 and 0
Date: Fri, 30 Mar 2007 23:27:58 +0000
To: martin [...] snowplow.org
From: Tels <nospam-abuse [...] bloodgate.com>
Download (untitled) / with headers
text/plain 1.6k
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Moin,. On Friday 30 March 2007 21:08:23 martin@snowplow.org wrote: Show quoted text
> " via RT" <bug-bignum@rt.cpan.org> writes:
> > <URL: http://rt.cpan.org/Ticket/Display.html?id=18025 > > > > > On Sat Jan 27 06:59:44 2007, TELS wrote:
> >> On Mon Mar 06 21:05:32 2006, guest wrote:
> >> > The following test code, when run on the stock cygwin build of perl > >> > 5.8.7, fails. Specifically, the value $ev prints as "1", but so > >> > does
> > > > Okay, the issue boils down to sometimes int(1.0) == 0 :( > > > > Since the value exp() returns results in int($ev) == 0, the constructed > > bigint number is wrong. This looks like a perl bug to me, so I posted a > > question to p5p about this. Here is a testscript showing it doesn't > > have to do anything with BigInt:
Oh, btw, you just discovered another bug: perl -Mbignum -le 'print exp(8)' 2980.95798704173 exp() should be overloaded but it isn't! Wow thank you :) All the best, Tels - -- Signed on Fri Mar 30 23:27:57 2007 with key 0x93B84C15. View my photo gallery: http://bloodgate.com/photos PGP key on http://bloodgate.com/tels.asc or per email. /* Too drunk - debug later */ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (GNU/Linux) iQEVAwUBRg2c/ncLPEOTuEwVAQIz/Qf+Kz8HRre9B7RTOlnack8fpnDi9KpiMgAu veHoE2FLp5NnT/jrnN+oukWqlpWjpoinnyvyauchnetdKaZMcW2IQTQ0pcqHmguD XOFfDv3PWy872M+EavFS7S4QsfwkSfqoss80zrxxP4g38jLp8DWI2f7Eqj/hnQh4 fr3apF9Wp2MfHDdCulZ3bXMBaPqvZ2kSWBr5wL7RF5nGzYhSseTat2ioiUIfnpls Up0wbOSKnXYoOas0tccG2RRzACZZbudN0XQdL4m55jlsARGuOFzQfEa/TsTb7Bia JekSpE3YD8Gv07pIWrzMMpn/euu7kK29QoCdT7EtWqUV8w+71q8GiQ== =/0jQ -----END PGP SIGNATURE-----
Download (untitled) / with headers
text/plain 568b
This issue has been fixed with the release of Math::BigInt 1.82. However, I am leaving this bug open because there are still 3 "holes" in the overloading, making it possible to recreate the situation: * cos(), sin() and atan2() are not "properly" overloaded: perl -MTest::More -wle 'plan tests=>2;my $e = cos(0.00000002); is ($e,"1","e == 1"); is(int($e),"1","int(e) == 1")' 1..2 ok 1 - e == 1 not ok 2 - int(e) == 1 # Failed test 'int(e) == 1' # in -e at line 1. # got: '0' # expected: '1' # Looks like you failed 1 test of 2. All the best, Tels
Download (untitled) / with headers
text/plain 379b
Marking this as resolved now: # perl -Mbignum -MTest::More -wle 'plan tests=>2;my $e = cos(0.000000000000000000001); is ($e,"1","e == 1"); is(int($e),"1","int(e) == 1")' 1..2 ok 1 - e == 1 ok 2 - int(e) == 1 e.g. cos(), sin() and atan2() are now properly overloaded. In addition, hex() and oct() are overloaded, too, so all the holes should be plugged now. All the best, Tels


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.