List Info

Thread: int(1.0) == 0?




int(1.0) == 0?
user name
2007-03-30 14:54:39
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Moin,

I now tracked the problem for this bugreport 
http:
//rt.cpan.org/Ticket/Display.html?id=18025 (filed in
bignum) down to 
some problem with int() and Look Ma!, I can replicate it
without bignum at 
all:

	telinux:~/perl/math/Math-BigInt-1.82> cat fail.pl
	#!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;

This produces under Perl 5.8.8:

	telinux:~/perl/math/Math-BigInt-1.82> perl fail.pl
	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.

Is this a known issue? As far as I can see, there should be
no difference 
between $nv and $ev, but for some reason int($ev) == 0,
which really 
confuses bignum - because deep down Calc::_new() does a
int($_[1]) which 
produces 0 instead of 1, so basically
Math::BigInt->new($ev) results in "0" 
instead of "1" and from there on everything goes
wrong.

All the best,

Tels

- -- 
 Signed on Fri Mar 30 19:49:41 2007 with key 0x93B84C15.
 View my photo gallery: http://bloodgate.com/phot
os
 PGP key on http://bloodgate.com/te
ls.asc or per email.

 "When it's done in 2001."

  -- 2000 Christmas card about Duke Nukem Forever (http://tinyurl.com/6m8nh
)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iQEVAwUBRg1rB3cLPEOTuEwVAQIddQf/VgdzL/JUuXuRtlC3QQrB+M8k27UF
MCHr
FQgnnjgTm88oTtjc0ydC4Cer7m3k3qpFQ91WaoIjKn/8XKEJ6vrreyNbbKRK
O5VZ
PRXobhYVXLsaZrR4Leixs/cJbuZlrDH9yf9Y2Mre9N7hbsAIOhXNGiijgjNO
2o7m
+p7MqMjymakQxpUK9Jrsm5Pq6oMlecHG2ck/KLCxysV92It3m3E6fJI0nUtj
gCiH
pjsYG/2oDhlk8IotfNpWnVZddDSVGsDMf/BEsCdy05+lSoyqNtTWKamDn767
bQWs
wojEYvUkVnnMp2tJognt627cBzqXYJVHYjELjUZhE/sstJMnAtFRUQ==
=W8eE
-----END PGP SIGNATURE-----

Re: int(1.0) == 0?
user name
2007-03-30 13:02:18
Tels wrote:
> 	is( int($ev), '1', 'int($ev) == 1');

is() implicitely does [string] 'eq' and not [numeric] '==',
so if you 
mean numeric equals, you must use:

	ok( int(nv) == 1, "testname");

John

-- 
John Peacock
Director of Information Research and Technology
Rowman & Littlefield Publishing Group
4501 Forbes Boulevard
Suite H
Lanham, MD  20706
301-459-3366 x.5010
fax 301-429-5748

Re: int(1.0) == 0?
user name
2007-03-30 15:12:59
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Moin,

On Friday 30 March 2007 18:02:18 John Peacock wrote:
> Tels wrote:
> > 	is( int($ev), '1', 'int($ev) == 1');
>
> is() implicitely does [string] 'eq' and not [numeric]
'==', so if you
> mean numeric equals, you must use:
>
> 	ok( int(nv) == 1, "testname");

This shouldn't matter, since int($ev) should be 1, and not
0. 

Adding your test just makes the testscript fail two tests
instead of one 

All the best,

Tels


- -- 
 Signed on Fri Mar 30 20:10:45 2007 with key 0x93B84C15.
 View my photo gallery: http://bloodgate.com/phot
os
 PGP key on http://bloodgate.com/te
ls.asc or per email.

 "Those are my principles, and if you don't like
them... well, I have
 others."

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

iQEVAwUBRg1vS3cLPEOTuEwVAQIxngf7BMunxEo/g8MdM/xRuIA7TWAspz7T
ZAvP
fYr2HssNOwRQ8rvB8BUuTbKLSl43Kt8egR+QBhoRstzkEIMbB5hzr+f8pPZF
8JlP
9zKKaCn+TJIBhj++zf7UPFpgtBp+SNXWcN+KiT2wHsKtFZZ68xDdABRyM0YG
aPK1
D4wt/JPWBTSYMwPGOc4z/ID9FrawhUSSb3Lk23PztlTQzt+zNEVIWkkCXT9M
Rozb
YEuUV8RQV/558Mqkxm83zdgY9BzsSnHcnxh1oskjrhcQsMwastZ7/4D2oD/Y
K73r
HE35D8puYiHRw+74TR659798TQrwU/J4y3xairhrsDOP+oShp+t5QQ==
=q5jH
-----END PGP SIGNATURE-----

Re: int(1.0) == 0?
user name
2007-03-30 13:17:32
Tels wrote:
> 	my $lnev = -7 / (10**17); my $ev=exp($lnev);
> 	my $nv = 1.0;
> 
> 	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.

This is a typical floating point equality issue.  $ev =
e^(-7/10^17) is not exactly 1.  Using my calculatator I
get:

    1 - e^(-7/10^17) = 1.11 * 10^-16.

So int($ev) == 0 is correct!

If you have precision requirements, then define and add
it before taking int():

    my $precision = 10 ** -15;
    my $result = int($ev + $precision);



 
____________________________________________________________
________________________
Be a PS3 game guru.
Get your game face on with the latest PS3 news and previews
at Yahoo! Games.

http://videogames.yahoo.com/platform?platform=120121

Re: int(1.0) == 0?
user name
2007-03-30 13:18:14
On Fri, Mar 30, 2007 at 08:12:59PM +0000, Tels wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Moin,
> 
> On Friday 30 March 2007 18:02:18 John Peacock wrote:
> > Tels wrote:
> > > 	is( int($ev), '1', 'int($ev) == 1');
> >
> > is() implicitely does [string] 'eq' and not
[numeric] '==', so if you
> > mean numeric equals, you must use:
> >
> > 	ok( int(nv) == 1, "testname");
> 
> This shouldn't matter, since int($ev) should be 1, and
not 0. 
> 
> Adding your test just makes the testscript fail two
tests instead of one 

Well, I also tried adding:

        cmp_ok($ev, '==', $nv);


and I then see

not ok 7
#   Failed test at fail.pl line 20.
#          got: 1
#     expected: 1
# Looks like you planned 6 tests but ran 1 extra.
# Looks like you failed 2 tests of 7 run.

So it appears that the two floating point values are
different, and whatever
perl is using to stringify them approximates both to
"1".

So I don't (quite) think that it's a Perl bug.

Nicholas Clark

Re: int(1.0) == 0?
user name
2007-03-30 13:22:23
Nicholas Clark wrote:
> So it appears that the two floating point values are
different, and whatever
> perl is using to stringify them approximates both to
"1".

Yeah, I was actually going to point out that Devel::Peek
does it's own 
form of stringification (through the underlying C library I
believe). 
I've been bitten by this before.  Try
printf("%.15f",$ev) and see what 
you get; it won't be 1 and I'll bet it involves a lot of 9's
after the 
decimal place...

John

-- 
John Peacock
Director of Information Research and Technology
Rowman & Littlefield Publishing Group
4501 Forbes Boulevard
Suite H
Lanham, MD  20706
301-459-3366 x.5010
fax 301-429-5748

Re: int(1.0) == 0?
user name
2007-03-30 13:45:46
On Fri, Mar 30, 2007 at 02:22:23PM -0400, John Peacock
wrote:
> Nicholas Clark wrote:
> >So it appears that the two floating point values
are different, and 
> >whatever
> >perl is using to stringify them approximates both
to "1".
> 
> Yeah, I was actually going to point out that
Devel::Peek does it's own 
> form of stringification (through the underlying C
library I believe). 
> I've been bitten by this before.  Try
printf("%.15f",$ev) and see what 
> you get; it won't be 1 and I'll bet it involves a lot
of 9's after the 
> decimal place...
> 

15 doesn't seem to be enough in this case, you have to go to
at least
%.16f:

  DB<1> x $ev
0  1
  DB<2> x sprintf "%.15f", $ev
0  1.000000000000000
  DB<3> x sprintf "%.16f", $ev
0  0.9999999999999999
  DB<4> x sprintf "%.20f", $ev
0  0.99999999999999988898

Ronald

Re: int(1.0) == 0?
user name
2007-03-30 15:47:32
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

- -----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

- - -----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Moin,

On Friday 30 March 2007 18:22:23 John Peacock wrote:
> Nicholas Clark wrote:
> > So it appears that the two floating point values
are different, and
> > whatever perl is using to stringify them
approximates both to "1".
>
> Yeah, I was actually going to point out that
Devel::Peek does it's own
> form of stringification (through the underlying C
library I believe).
> I've been bitten by this before.  Try
printf("%.15f",$ev) and see what
> you get; it won't be 1 and I'll bet it involves a lot
of 9's after the
> decimal place...

John, if you had actually read my original email entirely
(and maybe tried 
to run the test script  before
replying you would see that I did 
*exactly* that. And it still prints out
"1.0000000000". 

So if the result is "not entirely 0" (as I
suspected, but couldn't prove), 
it eludes me for now how to coerce Perl in telling me this
fact.

In addition, the reason for that the original bugreport that
"bigint" got 
called, not bignum. I guess the reason for *that* is that
the result 
stringifies as "1.0" and not
"0.99999999999". However, for now I cannot see 
how I could ever distinguish between these two cases as all
pure-Perl code 
so far always tells me that the number is 1.0 - except int()
who returns 0.

All the best,

Tels

- - - -- 
 Signed on Fri Mar 30 20:43:22 2007 with key 0x93B84C15.
 Get one of my photo posters: http://bloodgate.com/pos
ters
 PGP key on http://bloodgate.com/te
ls.asc or per email.

 "I want to squirt you a picture of my kids. You want
to squirt me back a
 video of your vacation. That's a software
experience."

  -- Steve Baller on the Zune
- - -----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iQEVAwUBRg121HcLPEOTuEwVAQJaNAf/S2tZcqoBJaAvDYajeQuaTQdySVzn
X13o
ZPpjSmWD4AdMJu+xqyX1MN6MxSClxMDYJ2CR95ZsboFVjPFffjEm1fYiymcC
g8QS
FenGSAQkJ00tFQIme1l1T80Tb+mXxoGskwEM1GQgz0KGhAz2YTolRfM3a2Am
9Yjl
8K27BUCXd8sub7qngzzxvMD3ecdptY11aWbtmbAcg9c7a2jJnsTCXbTDOi6F
WP+G
gbpLBgf3oo3yGe9nqBptqGEaU/KrFshGg9UuBNN4PeFjLGGDFFB7XQ39qxcJ
erE9
IMnVpgq6/GLqp45HC7DpLk0smrfJYBZIkydyHoU3AlS5YxiAgRaTdg==
=YpIB
- - -----END PGP SIGNATURE-----
- -----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iQEVAwUBRg13NncLPEOTuEwVAQLRvwf5AQiX8AK6S2Qjk+DLmCD+HKd42V64
WFgD
8F6BVnCF3BV/VhQLOUkI7V05ZQcpNMCD2UmrIKI7hvrHad0NkBbJVfosKQ6k
Bxam
UWq9nkXcqbWfyFHz/qQAAI0fE7RPaDKRRTD2SUTBxInxGXwlBhoukkRgai1e
KGwe
J9S9VfSfVV2r+l68A2wQ5BVizjCsBS4/eJfaHInpT8YiNGurGnhyWUAnZkDg
qMtW
vzUBFAH4ph43Uiwjjsut2BYBdENq0JRGGVKoLFLDgOxJrVUHuvOwPX4W9q9x
Z4KW
saSTxdXPUFqyGPeK6HjVPBHE8XYzbspG3nJuEqiULf9VJPkH2Q2KMg==
=X5/5
- -----END PGP SIGNATURE-----
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iQEVAwUBRg13ZHcLPEOTuEwVAQIuXwf5AeEPwN3VpPdEzrjq1mNQ9R8ga9yv
WYMx
N1ZblwnrfZa0jYr9DxJDmyMdF+mgKOIZviWsC2Tox5bsM3f1whgqbOc4t12E
WLsw
nKdqaYhezGapOpRbeacs8VPR9iF8w6DWBvLcgVOiUWbnOZHJWtIN/mBKpdOZ
BiCB
ow0eE2pvTZw98fvWtugF7rJ5C52SlhBbY/aveSI9jiom21s2kMGzsyzZtwja
b1Tb
biIrBI7QTqSsYeH54gYEbEz0CYLS/sXhLvVX2SXNtiHy4+OaaWj8W4PsKK4J
T+Dd
w/n9os9Oc0wmfOcgufY+AY4ViIMIBL7HOE8ncBBSIJnE4rGGaM4JOw==
=XH6A
-----END PGP SIGNATURE-----

Re: int(1.0) == 0?
user name
2007-03-30 15:49:14
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Moin,

On Friday 30 March 2007 18:45:46 Ronald J Kimball wrote:
> On Fri, Mar 30, 2007 at 02:22:23PM -0400, John Peacock
wrote:
> > Nicholas Clark wrote:
> > >So it appears that the two floating point
values are different, and
> > >whatever
> > >perl is using to stringify them approximates
both to "1".
> >
> > Yeah, I was actually going to point out that
Devel::Peek does it's own
> > form of stringification (through the underlying C
library I believe).
> > I've been bitten by this before.  Try
printf("%.15f",$ev) and see what
> > you get; it won't be 1 and I'll bet it involves a
lot of 9's after the
> > decimal place...
>
> 15 doesn't seem to be enough in this case, you have to
go to at least
> %.16f:
>
>   DB<1> x $ev
> 0  1
>   DB<2> x sprintf "%.15f", $ev
> 0  1.000000000000000
>   DB<3> x sprintf "%.16f", $ev
> 0  0.9999999999999999
>   DB<4> x sprintf "%.20f", $ev
> 0  0.99999999999999988898

DUH! I tried things like "%.15lf" etc. to coerce
it to get more precision 
but it always was 0.

Hm, now how do I teach bignum to distinguish between these
cases.

all the best,

Tels


- -- 
 Signed on Fri Mar 30 20:48:24 2007 with key 0x93B84C15.
 View my photo gallery: http://bloodgate.com/phot
os
 PGP key on http://bloodgate.com/te
ls.asc or per email.

 "I can imagine what you're thinking though: this girl
keeps her brains
 in her backside! But actually only the more primitive parts
of my brain
 are in my butt. The more interesting parts are kept in a PC
- my spinal
 cord is actually an RS232 lead!"

  -- Lucy, the OrangUtan Robot Girl http://tinyurl.com/3fv6z

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

iQEVAwUBRg13yncLPEOTuEwVAQJDDAf/VDZGySNzkVmqeF3rX4xJBcFOHUNQ
toaa
MqrjnwrtlstcF8sAJ8xgeZT/WleYFxvpbz22z0Ec0DD+d3lnYmJisCzodCuM
3Opd
hy/4yVb4w93O0o0tSjGfFrTTXBglhwH6GxaLPWZw9I1eCj3geQxgG98ZJpnv
CP+Z
il4cgzFg1Pvae/TS1BF0TBjIl/v+w0dD6xbkMiTRQabfauOeJS7aOQE73Yz/
Dps/
F7ESXcj9y7AMycNUBrAoNSxSPOk62uqLNZANi3uFa3HibB51YtasGXEB5Dr/
JfNj
LI1Mb6iT/kI1UnEspwoa/RT9gfHCX3rAeyCUpHtXp44m9teaKV/yBg==
=kKl3
-----END PGP SIGNATURE-----

Re: int(1.0) == 0?
user name
2007-03-30 16:14:28
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Moin,

On Friday 30 March 2007 20:47:32 Tels wrote:
> Moin,
[snip]
> In addition, the reason for that the original bugreport
that "bigint" got
> called, not bignum. I guess the reason for *that* is
that the result
> stringifies as "1.0" and not
"0.99999999999". However, for now I cannot
> see how I could ever distinguish between these two
cases as all pure-Perl
> code so far always tells me that the number is 1.0 -
except int() who
> returns 0.

I guess I just have to write a tiny portion of XS code that
does the right 
thing with IV or NV (or even just returns whether it is one
or the other 
and lets bignum do The Right Thing[tm].

All the best,

Tels

- -- 
 Signed on Fri Mar 30 21:13:31 2007 with key 0x93B84C15.
 Get one of my photo posters: http://bloodgate.com/pos
ters
 PGP key on http://bloodgate.com/te
ls.asc or per email.

 Mediawiki graph-extension: http://bloodgate.com
/perl/graph/

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

iQEVAwUBRg19tHcLPEOTuEwVAQJBuwf+LETHqylVZf9BAV2lco2sO0lxDmuY
lFz3
UgidC/LQujjW7z7Ax9T2DusuTjNf12hIzbev7VJ+Kb4Za36FERWFA6/qXdB/
YRKP
cfDNOe0EfIxUNtTMw5MGrL+PswIGDmKh82MYb0WuhUo8WARb0oa3NxXI0vA3
CHw3
eBuisWTn4cmqMXy+Hh1qDzuYVFSdHVs1N7nLS2r4ahge/qTDQqmgOcWPdP+Z
xbXc
/M9khqFNcw1VfaKqFuj1MzNTgfnSQCR/kA7G0ppSoEgRn+VUroIXd2t2R9Hl
k2uD
N/hgIfEXpDF3v7hAALiYPtid9QLv8LD5yOUcCNCWUUzd/3jxdjSGMA==
=HGAs
-----END PGP SIGNATURE-----

[1-10]

about | contact  Other archives ( Real Estate discussion Medical topics )