Re: Ask for recommended module for precise number
- From: "harryfmudd [AT] comcast [DOT] net" <"harryfmudd [AT] comcast [DOT] net">
- Date: Tue, 24 Jan 2006 23:48:04 -0500
Tom wrote:
Hi Sisyphus,
Thanks a lots for your pointers to those useful library.
I think I did not describe my question well. In fact, I am getting trouble into some VERY SMALL number which are close to zero. Consider two number: "a" is 2^(-100) and "b" is 2^(-99). Then, "a/b" is 0.1.
It seems that BigFloat does not work for very small number as follows: ============================================================= use Math::BigFloat; use Carp;
my $x = new Math::BigFloat(0.1);
foreach my $i (0..100) { confess ("It become zero at $i-th iteration") if ($x == 0); $x = $x * $x;
printf "$i: %.5f\n", $x; } =============================================================
The $x in the above program become "0.0" if using original PERL operations but become "1.0" (wrong number) if using Math::BigFloat.
As I am dealing with values of joint probabilities density, some values are very very small. Currently I use log() to handle those problems but it will introduce some errors if I need to do operations (e.g., addition) in the real space.
I have a try in GMP after reading your post, but it still convert to "0.0" after a 10 times of mulitplication of "0.1".
Tom
Appearances can be deceiving. The problem appears to be the inability of printf to format really really small numbers. Replacing your
printf "$i: %.5f\n", $x
with
printf "$i: %s\n", $x->bsstr ()
(gotten from reading the Math::BigFloat docs) I get the following output:
0: 1e-2 1: 1e-4 2: 1e-8 3: 1e-16 4: 1e-32 5: 1e-64 6: 1e-128 7: 1e-256 8: 1e-512 9: 1e-1024 10: 1e-2048 11: 1e-4096 12: 1e-8192 13: 1e-16384 14: 1e-32768 15: 1e-65536 16: 1e-131072 17: 1e-262144 18: 1e-524288 19: 1e-1048576 20: 1e-2097152 21: 1e-4194304 22: 1e-8388608 23: 1e-16777216 24: 1e-33554432 25: 1e-67108864 26: 1e-134217728 27: 1e-268435456 28: 1e-536870912 29: 1e-1073741824 30: 1e-2147483648 31: 1e-4294967296 32: 1e-8589934592 33: 1e-17179869184 34: 1e-34359738368 35: 1e-68719476736 36: 1e-137438953472 37: 1e-274877906944 38: 1e-549755813888 39: 1e-1099511627776 40: 1e-2199023255552 41: 1e-4398046511104 42: 1e-8796093022208 43: 1e-17592186044416 44: 1e-35184372088832 45: 1e-70368744177664 46: 1e-140737488355328 47: 1e-281474976710656 48: 1e-562949953421312 49: 1e-1125899906842624 50: 1e-2251799813685248 51: 1e-4503599627370496 52: 1e-9007199254740992 53: 1e-18014398509481984 54: 1e-36028797018963968 55: 1e-72057594037927936 56: 1e-144115188075855872 57: 1e-288230376151711744 58: 1e-576460752303423488 59: 1e-1152921504606846976 60: 1e-2305843009213693952 61: 1e-4611686018427387904 62: 1e-9223372036854775808 63: 1e-18446744073709551616 64: 1e-36893488147419103232 65: 1e-73786976294838206464 66: 1e-147573952589676412928 67: 1e-295147905179352825856 68: 1e-590295810358705651712 69: 1e-1180591620717411303424 70: 1e-2361183241434822606848 71: 1e-4722366482869645213696 72: 1e-9444732965739290427392 73: 1e-18889465931478580854784 74: 1e-37778931862957161709568 75: 1e-75557863725914323419136 76: 1e-151115727451828646838272 77: 1e-302231454903657293676544 78: 1e-604462909807314587353088 79: 1e-1208925819614629174706176 80: 1e-2417851639229258349412352 81: 1e-4835703278458516698824704 82: 1e-9671406556917033397649408 83: 1e-19342813113834066795298816 84: 1e-38685626227668133590597632 85: 1e-77371252455336267181195264 86: 1e-154742504910672534362390528 87: 1e-309485009821345068724781056 88: 1e-618970019642690137449562112 89: 1e-1237940039285380274899124224 90: 1e-2475880078570760549798248448 91: 1e-4951760157141521099596496896 92: 1e-9903520314283042199192993792 93: 1e-19807040628566084398385987584 94: 1e-39614081257132168796771975168 95: 1e-79228162514264337593543950336 96: 1e-158456325028528675187087900672 97: 1e-316912650057057350374175801344 98: 1e-633825300114114700748351602688 99: 1e-1267650600228229401496703205376 100: 1e-2535301200456458802993406410752
Are those numbers small enough for you? The entire script is appended.
Tom Wyant
use Math::BigFloat; use Carp;
my $x = new Math::BigFloat(0.1);
foreach my $i (0..100) {
confess ("It become zero at $i-th iteration") if ($x == 0);
$x = $x * $x;# printf "$i: %.5f\n", $x;
printf "$i: %s\n", $x->bsstr ();
# the following actually works also, but after a while you get
# too many zeros to tell what's going on.
# print "$i: $x\n\n";
}
.- Follow-Ups:
- References:
- Ask for recommended module for precise number
- From: Tom
- Re: Ask for recommended module for precise number
- From: Sisyphus
- Re: Ask for recommended module for precise number
- From: Tom
- Ask for recommended module for precise number
- Prev by Date: Re: Ask for recommended module for precise number
- Next by Date: Re: Ask for recommended module for precise number
- Previous by thread: Re: Ask for recommended module for precise number
- Next by thread: Re: Ask for recommended module for precise number
- Index(es):
Relevant Pages
|
|