Re: Ask for recommended module for precise number



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";
}
.



Relevant Pages

  • Re: Ask for recommended module for precise number
    ... use Carp; ... For the printf() issue, it seems to be inconsistency between the string ... > Tom wrote: ... >> trouble into some VERY SMALL number which are close to zero. ...
    (comp.lang.perl.modules)
  • Re: Soft-hyphens or breakable points in a string
    ... >> quite some trouble when it doesn't. ... I meant zero width space instead of zero ... (I usually write web pages more carefully than Usenet postings). ... Pages about Web authoring: http://www.cs.tut.fi/~jkorpela/www.html ...
    (comp.infosystems.www.authoring.html)
  • Re: [RFC 00/15] x86_64: Optimize percpu accesses
    ... a base of zero is a base of -32K or so. ... Only trouble that would get us ... manually managing the per cpu area size again. ...
    (Linux-Kernel)
  • Re: Ask for recommended module for precise number
    ... Tom wrote: ... > use Carp; ... > and the printf() function. ... >>> trouble into some VERY SMALL number which are close to zero. ...
    (comp.lang.perl.modules)
  • Re: Acct cleared on IGS (lol)
    ... to zero and my registration date has been set to zero (here represented ... using panda-glGo 1.4, I myself recently had similar trouble, getting ... bumped off every 20-30 minutes while trying to watch pro games. ...
    (rec.games.go)