Re: Ask for recommended module for precise number
- From: "Tom" <chi.lun@xxxxxxxxx>
- Date: 24 Jan 2006 23:02:00 -0800
Sorry, I should call you "Tom"...........
Tom wrote:
> Hi Harry,
>
> Thanks for you help. It was really my misunderstanding before. I write
> another program which simulate my typical application: calculating
> posterior from prior and likelihood, which are very small number.
>
> ================================================================
> use strict;
>
> use Math::BigFloat;
> use Carp;
>
> my $x = new Math::BigFloat(0.1);
> my $y = new Math::BigFloat(0.1);
> my $num = 100;
>
> foreach my $i (0..$num) {
> $x = $x * 0.1;
> }
> foreach my $j (0..$num-1) {
> $y = $y * 0.1;
> }
>
> my $z = $x/$y;
>
> printf "z: %.5f\n", $z;
> ================================================================
> Now, the z is "0.1". It fits my usage as those small numbers are only
> stored internally. :)
>
>
> For the printf() issue, it seems to be inconsistency between the string
> and the printf() function. I have tried the following tiny program:
>
> ================================================================
> use strict;
> use Carp;
>
> my $i = 0;
> while (1) {
> my $zeroString = join('', map { "0" } (1..$i));
> my $numString = sprintf("0.%s1", $zeroString);
> eval {
> printf "%d: %.5f\n", $i, $numString;
> };
> confess ($@) if ($@);
>
> # confess (qq{Convert to "0" at $i-th iterations.\n}) if ($numString
> == 0);
>
> $i++;
> }
> ================================================================
> With the "commented" statement, the program always output "0.00000"
> without error (the program was terminated at 9xxx-th iterations).
>
> With the "commented" statement, the program converts to "0" at around
> 300 iterations. (it means the Math::BigFloat case is not reproductable
> at normal PERL operations?)
>
>
> Tom
>
>
>
> harryfmudd [AT] comcast [DOT] net wrote:
> > 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:
- Re: Ask for recommended module for precise number
- From: harryfmudd [AT] comcast [DOT] net
- Re: Ask for recommended module for precise number
- 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
- Re: Ask for recommended module for precise number
- From: harryfmudd [AT] comcast [DOT] net
- 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
|
|