remove hardcoded cmd shell in testsuite
[p5sagit/p5-mst-13.2.git] / lib / Math / BigFloat.pm
CommitLineData
58cde26e 1#!/usr/bin/perl -w
2
58cde26e 3# The following hash values are internally used:
4# _e: exponent (BigInt)
5# _m: mantissa (absolute BigInt)
6# sign: +,-,"NaN" if not a number
7# _a: accuracy
8# _p: precision
0716bf9b 9# _f: flags, used to signal MBI not to touch our private parts
58cde26e 10# _cow: Copy-On-Write (NRY)
11
a0d0e21e 12package Math::BigFloat;
13
0716bf9b 14$VERSION = 1.16;
58cde26e 15require 5.005;
16use Exporter;
0716bf9b 17use Math::BigInt qw/objectify/;
58cde26e 18@ISA = qw( Exporter Math::BigInt);
19# can not export bneg/babs since the are only in MBI
20@EXPORT_OK = qw(
21 bcmp
22 badd bmul bdiv bmod bnorm bsub
23 bgcd blcm bround bfround
24 bpow bnan bzero bfloor bceil
25 bacmp bstr binc bdec bint binf
0716bf9b 26 is_odd is_even is_nan is_inf is_positive is_negative
58cde26e 27 is_zero is_one sign
28 );
a0d0e21e 29
58cde26e 30#@EXPORT = qw( );
31use strict;
32use vars qw/$AUTOLOAD $accuracy $precision $div_scale $rnd_mode/;
33my $class = "Math::BigFloat";
a0d0e21e 34
a5f75d66 35use overload
58cde26e 36'<=>' => sub {
37 $_[2] ?
38 $class->bcmp($_[1],$_[0]) :
39 $class->bcmp($_[0],$_[1])},
0716bf9b 40'int' => sub { $_[0]->as_number() }, # 'trunc' to bigint
a5f75d66 41;
a0d0e21e 42
0716bf9b 43##############################################################################
44# global constants, flags and accessory
45
46use constant MB_NEVER_ROUND => 0x0001;
47
58cde26e 48# are NaNs ok?
49my $NaNOK=1;
58cde26e 50# constant for easier life
51my $nan = 'NaN';
52my $ten = Math::BigInt->new(10); # shortcut for speed
53
54# Rounding modes one of 'even', 'odd', '+inf', '-inf', 'zero' or 'trunc'
55$rnd_mode = 'even';
56$accuracy = undef;
57$precision = undef;
58$div_scale = 40;
59
60{
61 # checks for AUTOLOAD
62 my %methods = map { $_ => 1 }
63 qw / fadd fsub fmul fdiv fround ffround fsqrt fmod fstr fsstr fpow fnorm
64 fabs fneg fint fcmp fzero fnan finc fdec
65 /;
66
67 sub method_valid { return exists $methods{$_[0]||''}; }
a0d0e21e 68}
0e8b9368 69
58cde26e 70##############################################################################
71# constructors
a0d0e21e 72
58cde26e 73sub new
74 {
75 # create a new BigFloat object from a string or another bigfloat object.
76 # _e: exponent
77 # _m: mantissa
78 # sign => sign (+/-), or "NaN"
a0d0e21e 79
58cde26e 80 my $class = shift;
81
82 my $wanted = shift; # avoid numify call by not using || here
83 return $class->bzero() if !defined $wanted; # default to 0
84 return $wanted->copy() if ref($wanted) eq $class;
a0d0e21e 85
58cde26e 86 my $round = shift; $round = 0 if !defined $round; # no rounding as default
87 my $self = {}; bless $self, $class;
b22b3e31 88 # shortcut for bigints and its subclasses
0716bf9b 89 if ((ref($wanted)) && (ref($wanted) ne $class))
58cde26e 90 {
0716bf9b 91 $self->{_m} = $wanted->as_number(); # get us a bigint copy
58cde26e 92 $self->{_e} = Math::BigInt->new(0);
93 $self->{_m}->babs();
94 $self->{sign} = $wanted->sign();
0716bf9b 95 return $self->bnorm();
58cde26e 96 }
97 # got string
98 # handle '+inf', '-inf' first
99 if ($wanted =~ /^[+-]inf$/)
100 {
101 $self->{_e} = Math::BigInt->new(0);
102 $self->{_m} = Math::BigInt->new(0);
103 $self->{sign} = $wanted;
0716bf9b 104 return $self->bnorm();
58cde26e 105 }
106 #print "new string '$wanted'\n";
107 my ($mis,$miv,$mfv,$es,$ev) = Math::BigInt::_split(\$wanted);
108 if (!ref $mis)
109 {
110 die "$wanted is not a number initialized to $class" if !$NaNOK;
111 $self->{_e} = Math::BigInt->new(0);
112 $self->{_m} = Math::BigInt->new(0);
113 $self->{sign} = $nan;
114 }
115 else
116 {
117 # make integer from mantissa by adjusting exp, then convert to bigint
118 $self->{_e} = Math::BigInt->new("$$es$$ev"); # exponent
119 $self->{_m} = Math::BigInt->new("$$mis$$miv$$mfv"); # create mantissa
120 # 3.123E0 = 3123E-3, and 3.123E-2 => 3123E-5
121 $self->{_e} -= CORE::length($$mfv);
122 $self->{sign} = $self->{_m}->sign(); $self->{_m}->babs();
123 }
0716bf9b 124 #print "$wanted => $self->{sign} $self->{value}\n";
58cde26e 125 $self->bnorm(); # first normalize
126 # if any of the globals is set, round to them and thus store them insid $self
127 $self->round($accuracy,$precision,$rnd_mode)
128 if defined $accuracy || defined $precision;
129 return $self;
130 }
a0d0e21e 131
58cde26e 132# some shortcuts for easier life
133sub bfloat
134 {
135 # exportable version of new
58cde26e 136 return $class->new(@_);
137 }
138
139sub bint
140 {
141 # exportable version of new
58cde26e 142 return $class->new(@_,0)->bround(0,'trunc');
143 }
144
145sub bnan
146 {
147 # create a bigfloat 'NaN', if given a BigFloat, set it to 'NaN'
148 my $self = shift;
149 $self = $class if !defined $self;
150 if (!ref($self))
288d023a 151 {
58cde26e 152 my $c = $self; $self = {}; bless $self, $c;
a0d0e21e 153 }
58cde26e 154 $self->{_e} = new Math::BigInt 0;
155 $self->{_m} = new Math::BigInt 0;
156 $self->{sign} = $nan;
58cde26e 157 return $self;
158 }
a0d0e21e 159
58cde26e 160sub binf
161 {
162 # create a bigfloat '+-inf', if given a BigFloat, set it to '+-inf'
163 my $self = shift;
164 my $sign = shift; $sign = '+' if !defined $sign || $sign ne '-';
a0d0e21e 165
58cde26e 166 $self = $class if !defined $self;
167 if (!ref($self))
168 {
169 my $c = $self; $self = {}; bless $self, $c;
170 }
171 $self->{_e} = new Math::BigInt 0;
172 $self->{_m} = new Math::BigInt 0;
173 $self->{sign} = $sign.'inf';
58cde26e 174 return $self;
175 }
a0d0e21e 176
58cde26e 177sub bzero
178 {
179 # create a bigfloat '+0', if given a BigFloat, set it to 0
180 my $self = shift;
181 $self = $class if !defined $self;
182 if (!ref($self))
183 {
184 my $c = $self; $self = {}; bless $self, $c;
185 }
186 $self->{_m} = new Math::BigInt 0;
187 $self->{_e} = new Math::BigInt 1;
188 $self->{sign} = '+';
58cde26e 189 return $self;
190 }
191
192##############################################################################
193# string conversation
194
195sub bstr
196 {
197 # (ref to BFLOAT or num_str ) return num_str
198 # Convert number from internal format to (non-scientific) string format.
199 # internal format is always normalized (no leading zeros, "-0" => "+0")
58cde26e 200 my ($self,$x) = objectify(1,@_);
201
202 #return "Oups! e was $nan" if $x->{_e}->{sign} eq $nan;
203 #return "Oups! m was $nan" if $x->{_m}->{sign} eq $nan;
204 return $x->{sign} if $x->{sign} !~ /^[+-]$/;
205 return '0' if $x->is_zero();
206
207 my $es = $x->{_m}->bstr();
208 if ($x->{_e}->is_zero())
209 {
210 $es = $x->{sign}.$es if $x->{sign} eq '-';
211 return $es;
212 }
213
214 if ($x->{_e}->sign() eq '-')
215 {
216 if ($x->{_e} <= -CORE::length($es))
217 {
218 # print "style: 0.xxxx\n";
219 my $r = $x->{_e}->copy(); $r->babs()->bsub( CORE::length($es) );
220 $es = '0.'. ('0' x $r) . $es;
221 }
222 else
223 {
224 # print "insert '.' at $x->{_e} in '$es'\n";
225 substr($es,$x->{_e},0) = '.';
82cf049f 226 }
82cf049f 227 }
58cde26e 228 else
229 {
230 # expand with zeros
231 $es .= '0' x $x->{_e};
232 }
233 $es = $x->{sign}.$es if $x->{sign} eq '-';
234 return $es;
82cf049f 235 }
f216259d 236
58cde26e 237sub bsstr
238 {
239 # (ref to BFLOAT or num_str ) return num_str
240 # Convert number from internal format to scientific string format.
241 # internal format is always normalized (no leading zeros, "-0E0" => "+0E0")
58cde26e 242 my ($self,$x) = objectify(1,@_);
a0d0e21e 243
58cde26e 244 return "Oups! e was $nan" if $x->{_e}->{sign} eq $nan;
245 return "Oups! m was $nan" if $x->{_m}->{sign} eq $nan;
246 return $x->{sign} if $x->{sign} !~ /^[+-]$/;
247 my $sign = $x->{_e}->{sign}; $sign = '' if $sign eq '-';
248 my $sep = 'e'.$sign;
249 return $x->{_m}->bstr().$sep.$x->{_e}->bstr();
250 }
251
252sub numify
253 {
254 # Make a number from a BigFloat object
255 # simple return string and let Perl's atoi() handle the rest
58cde26e 256 my ($self,$x) = objectify(1,@_);
257 return $x->bsstr();
258 }
a0d0e21e 259
58cde26e 260##############################################################################
261# public stuff (usually prefixed with "b")
262
263# really? Just for exporting them is not what I had in mind
264#sub babs
265# {
266# $class->SUPER::babs($class,@_);
267# }
268#sub bneg
269# {
270# $class->SUPER::bneg($class,@_);
271# }
272#sub bnot
273# {
274# $class->SUPER::bnot($class,@_);
275# }
276
277sub bcmp
278 {
279 # Compares 2 values. Returns one of undef, <0, =0, >0. (suitable for sort)
280 # (BFLOAT or num_str, BFLOAT or num_str) return cond_code
281 my ($self,$x,$y) = objectify(2,@_);
58cde26e 282
0716bf9b 283 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
284 {
285 # handle +-inf and NaN
286 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
287 return 0 if ($x->{sign} eq $y->{sign}) && ($x->{sign} =~ /^[+-]inf$/);
288 return +1 if $x->{sign} eq '+inf';
289 return -1 if $x->{sign} eq '-inf';
290 return -1 if $y->{sign} eq '+inf';
291 return +1 if $y->{sign} eq '-inf';
292 }
293
294 # check sign for speed first
58cde26e 295 return 1 if $x->{sign} eq '+' && $y->{sign} eq '-';
296 return -1 if $x->{sign} eq '-' && $y->{sign} eq '+'; # does also -x <=> 0
297
298 return 0 if $x->is_zero() && $y->is_zero(); # 0 <=> 0
299 return -1 if $x->is_zero() && $y->{sign} eq '+'; # 0 <=> +y
300 return 1 if $y->is_zero() && $x->{sign} eq '+'; # +x <=> 0
301
302 # adjust so that exponents are equal
303 my $lx = $x->{_m}->length() + $x->{_e};
304 my $ly = $y->{_m}->length() + $y->{_e};
305 # print "x $x y $y lx $lx ly $ly\n";
306 my $l = $lx - $ly; $l = -$l if $x->{sign} eq '-';
307 # print "$l $x->{sign}\n";
308 return $l if $l != 0;
309
0716bf9b 310 # lengths are equal, so compare mantissa, if equal, compare exponents
b22b3e31 311 # this assumes normalized numbers (no trailing zeros etc!)
58cde26e 312 my $rc = $x->{_m} <=> $y->{_m} || $x->{_e} <=> $y->{_e};
313 $rc = -$rc if $x->{sign} eq '-'; # -124 < -123
314 return $rc;
315 }
316
317sub bacmp
318 {
319 # Compares 2 values, ignoring their signs.
320 # Returns one of undef, <0, =0, >0. (suitable for sort)
321 # (BFLOAT or num_str, BFLOAT or num_str) return cond_code
322 my ($self,$x,$y) = objectify(2,@_);
323 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
324
325 # signs are ignored, so check length
326 # length(x) is length(m)+e aka length of non-fraction part
327 # the longer one is bigger
328 my $l = $x->length() - $y->length();
329 #print "$l\n";
330 return $l if $l != 0;
331 #print "equal lengths\n";
332
333 # if both are equal long, make full compare
334 # first compare only the mantissa
335 # if mantissa are equal, compare fractions
336
337 return $x->{_m} <=> $y->{_m} || $x->{_e} <=> $y->{_e};
338 }
a0d0e21e 339
58cde26e 340sub badd
341 {
342 # add second arg (BFLOAT or string) to first (BFLOAT) (modifies first)
343 # return result as BFLOAT
58cde26e 344 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
345
58cde26e 346 return $x->bnan() if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
0716bf9b 347
58cde26e 348 # speed: no add for 0+y or x+0
349 return $x if $y->is_zero(); # x+0
350 if ($x->is_zero()) # 0+y
351 {
352 # make copy, clobbering up x (modify in place!)
353 $x->{_e} = $y->{_e}->copy();
354 $x->{_m} = $y->{_m}->copy();
355 $x->{sign} = $y->{sign} || $nan;
356 return $x->round($a,$p,$r,$y);
a0d0e21e 357 }
58cde26e 358
359 # take lower of the two e's and adapt m1 to it to match m2
360 my $e = $y->{_e}; $e = Math::BigInt::bzero() if !defined $e; # if no BFLOAT
361 $e = $e - $x->{_e};
362 my $add = $y->{_m}->copy();
363 if ($e < 0)
364 {
0716bf9b 365 # print "e < 0\n";
58cde26e 366 #print "\$x->{_m}: $x->{_m} ";
367 #print "\$x->{_e}: $x->{_e}\n";
368 my $e1 = $e->copy()->babs();
369 $x->{_m} *= (10 ** $e1);
370 $x->{_e} += $e; # need the sign of e
371 #$x->{_m} += $y->{_m};
372 #print "\$x->{_m}: $x->{_m} ";
373 #print "\$x->{_e}: $x->{_e}\n";
374 }
375 elsif ($e > 0)
376 {
0716bf9b 377 # print "e > 0\n";
58cde26e 378 #print "\$x->{_m}: $x->{_m} \$y->{_m}: $y->{_m} \$e: $e ",ref($e),"\n";
379 $add *= (10 ** $e);
380 #$x->{_m} += $y->{_m} * (10 ** $e);
381 #print "\$x->{_m}: $x->{_m}\n";
382 }
383 # else: both e are same, so leave them
384 #print "badd $x->{sign}$x->{_m} + $y->{sign}$add\n";
385 # fiddle with signs
386 $x->{_m}->{sign} = $x->{sign};
387 $add->{sign} = $y->{sign};
388 # finally do add/sub
389 $x->{_m} += $add;
390 # re-adjust signs
391 $x->{sign} = $x->{_m}->{sign};
392 $x->{_m}->{sign} = '+';
0716bf9b 393 #$x->bnorm(); # delete trailing zeros
58cde26e 394 return $x->round($a,$p,$r,$y);
395 }
396
397sub bsub
398 {
0716bf9b 399 # (BigFloat or num_str, BigFloat or num_str) return BigFloat
58cde26e 400 # subtract second arg from first, modify first
401 my ($self,$x,$y) = objectify(2,@_);
a0d0e21e 402
58cde26e 403 $x->badd($y->bneg()); # badd does not leave internal zeros
404 $y->bneg(); # refix y, assumes no one reads $y in between
0716bf9b 405 return $x; # badd() already normalized and rounded
58cde26e 406 }
407
408sub binc
409 {
410 # increment arg by one
411 my ($self,$x,$a,$p,$r) = objectify(1,@_);
58cde26e 412 $x->badd($self->_one())->round($a,$p,$r);
413 }
414
415sub bdec
416 {
417 # decrement arg by one
418 my ($self,$x,$a,$p,$r) = objectify(1,@_);
58cde26e 419 $x->badd($self->_one('-'))->round($a,$p,$r);
420 }
421
422sub blcm
423 {
424 # (BINT or num_str, BINT or num_str) return BINT
425 # does not modify arguments, but returns new object
426 # Lowest Common Multiplicator
58cde26e 427
428 my ($self,@arg) = objectify(0,@_);
429 my $x = $self->new(shift @arg);
430 while (@arg) { $x = _lcm($x,shift @arg); }
431 $x;
432 }
433
434sub bgcd
435 {
436 # (BINT or num_str, BINT or num_str) return BINT
437 # does not modify arguments, but returns new object
438 # GCD -- Euclids algorithm Knuth Vol 2 pg 296
58cde26e 439
440 my ($self,@arg) = objectify(0,@_);
441 my $x = $self->new(shift @arg);
442 while (@arg) { $x = _gcd($x,shift @arg); }
443 $x;
444 }
445
446sub is_zero
447 {
448 # return true if arg (BINT or num_str) is zero (array '+', '0')
449 my $x = shift; $x = $class->new($x) unless ref $x;
450 #my ($self,$x) = objectify(1,@_);
58cde26e 451 return ($x->{sign} ne $nan && $x->{_m}->is_zero());
452 }
453
454sub is_one
455 {
456 # return true if arg (BINT or num_str) is +1 (array '+', '1')
457 # or -1 if signis given
458 my $x = shift; $x = $class->new($x) unless ref $x;
459 #my ($self,$x) = objectify(1,@_);
460 my $sign = $_[2] || '+';
461 return ($x->{sign} eq $sign && $x->{_e}->is_zero() && $x->{_m}->is_one());
462 }
463
464sub is_odd
465 {
b22b3e31 466 # return true if arg (BINT or num_str) is odd or false if even
58cde26e 467 my $x = shift; $x = $class->new($x) unless ref $x;
468 #my ($self,$x) = objectify(1,@_);
0716bf9b 469
470 return 0 if $x->{sign} !~ /^[+-]$/; # NaN & +-inf aren't
471 return ($x->{_e}->is_zero() && $x->{_m}->is_odd());
58cde26e 472 }
473
474sub is_even
475 {
b22b3e31 476 # return true if arg (BINT or num_str) is even or false if odd
58cde26e 477 my $x = shift; $x = $class->new($x) unless ref $x;
478 #my ($self,$x) = objectify(1,@_);
0716bf9b 479
480 return 0 if $x->{sign} !~ /^[+-]$/; # NaN & +-inf aren't
481 return 1 if $x->{_m}->is_zero(); # 0e1 is even
482 return ($x->{_e}->is_zero() && $x->{_m}->is_even()); # 123.45 is never
58cde26e 483 }
484
485sub bmul
486 {
487 # multiply two numbers -- stolen from Knuth Vol 2 pg 233
488 # (BINT or num_str, BINT or num_str) return BINT
489 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
58cde26e 490
0716bf9b 491 # print "mbf bmul $x->{_m}e$x->{_e} $y->{_m}e$y->{_e}\n";
58cde26e 492 return $x->bnan() if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
493
58cde26e 494 # aEb * cEd = (a*c)E(b+d)
495 $x->{_m} = $x->{_m} * $y->{_m};
496 #print "m: $x->{_m}\n";
497 $x->{_e} = $x->{_e} + $y->{_e};
498 #print "e: $x->{_m}\n";
499 # adjust sign:
500 $x->{sign} = $x->{sign} ne $y->{sign} ? '-' : '+';
501 #print "s: $x->{sign}\n";
0716bf9b 502 $x->bnorm();
58cde26e 503 return $x->round($a,$p,$r,$y);
504 }
505
506sub bdiv
507 {
508 # (dividend: BFLOAT or num_str, divisor: BFLOAT or num_str) return
509 # (BFLOAT,BFLOAT) (quo,rem) or BINT (only rem)
510 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
511
512 return wantarray ? ($x->bnan(),bnan()) : $x->bnan()
513 if ($x->{sign} eq $nan || $y->is_nan() || $y->is_zero());
0716bf9b 514
515 $y = $class->new($y) if ref($y) ne $class; # promote bigints
516
517 # print "mbf bdiv $x ",ref($x)," ",$y," ",ref($y),"\n";
58cde26e 518 # we need to limit the accuracy to protect against overflow
0716bf9b 519 my ($scale) = $x->_scale_a($accuracy,$rnd_mode,$a,$r); # ignore $p
58cde26e 520 if (!defined $scale)
521 {
0716bf9b 522 # simulate old behaviour
523 $scale = $div_scale+1; # one more for proper riund
524 $a = $div_scale; # and round to it
a0d0e21e 525 }
0716bf9b 526 my $lx = $x->{_m}->length(); my $ly = $y->{_m}->length();
58cde26e 527 $scale = $lx if $lx > $scale;
58cde26e 528 $scale = $ly if $ly > $scale;
529 #print "scale $scale $lx $ly\n";
0716bf9b 530 my $diff = $ly - $lx;
531 $scale += $diff if $diff > 0; # if lx << ly, but not if ly << lx!
a0d0e21e 532
58cde26e 533 return wantarray ? ($x,$self->bzero()) : $x if $x->is_zero();
534
535 $x->{sign} = $x->{sign} ne $y->sign() ? '-' : '+';
a0d0e21e 536
58cde26e 537 # check for / +-1 ( +/- 1E0)
538 if ($y->is_one())
539 {
540 return wantarray ? ($x,$self->bzero()) : $x;
a0d0e21e 541 }
a5f75d66 542
58cde26e 543 # a * 10 ** b / c * 10 ** d => a/c * 10 ** (b-d)
544 #print "self: $self x: $x ref(x) ", ref($x)," m: $x->{_m}\n";
545 # my $scale_10 = 10 ** $scale; $x->{_m}->bmul($scale_10);
546 $x->{_m}->blsft($scale,10);
0716bf9b 547 #print "m: $x->{_m} $y->{_m}\n";
58cde26e 548 $x->{_m}->bdiv( $y->{_m} ); # a/c
549 #print "m: $x->{_m}\n";
550 #print "e: $x->{_e} $y->{_e}",$scale,"\n";
551 $x->{_e}->bsub($y->{_e}); # b-d
552 #print "e: $x->{_e}\n";
553 $x->{_e}->bsub($scale); # correct for 10**scale
0716bf9b 554 #print "after div: m: $x->{_m} e: $x->{_e}\n";
555 $x->bnorm(); # remove trailing 0's
556 #print "after div: m: $x->{_m} e: $x->{_e}\n";
557 $x->round($a,$p,$r); # then round accordingly
558
58cde26e 559 if (wantarray)
560 {
561 my $rem = $x->copy();
562 $rem->bmod($y,$a,$p,$r);
0716bf9b 563 return ($x,$rem);
58cde26e 564 }
565 return $x;
566 }
a0d0e21e 567
58cde26e 568sub bmod
569 {
570 # (dividend: BFLOAT or num_str, divisor: BFLOAT or num_str) return reminder
571 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
a0d0e21e 572
58cde26e 573 return $x->bnan() if ($x->{sign} eq $nan || $y->is_nan() || $y->is_zero());
574 return $x->bzero() if $y->is_one();
575
576 # XXX tels: not done yet
577 return $x->round($a,$p,$r,$y);
578 }
579
580sub bsqrt
581 {
0716bf9b 582 # calculate square root; this should probably
583 # use a different test to see whether the accuracy we want is...
58cde26e 584 my ($self,$x,$a,$p,$r) = objectify(1,@_);
585
0716bf9b 586 return $x->bnan() if $x->{sign} eq 'NaN' || $x->{sign} =~ /^-/; # <0, NaN
587 return $x if $x->{sign} eq '+inf'; # +inf
58cde26e 588 return $x if $x->is_zero() || $x == 1;
589
0716bf9b 590 # we need to limit the accuracy to protect against overflow
591 my ($scale) = $x->_scale_a($accuracy,$rnd_mode,$a,$r); # ignore $p
592 if (!defined $scale)
593 {
594 # simulate old behaviour
595 $scale = $div_scale+1; # one more for proper riund
596 $a = $div_scale; # and round to it
597 }
598 my $lx = $x->{_m}->length();
599 $scale = $lx if $scale < $lx;
58cde26e 600 my $e = Math::BigFloat->new("1E-$scale"); # make test variable
601 return $x->bnan() if $e->sign() eq 'NaN';
602
58cde26e 603 # start with some reasonable guess
0716bf9b 604 #$x *= 10 ** ($len - $org->{_e}); $x /= 2; # !?!?
605 $lx = 1 if $lx < 1;
606 my $gs = Math::BigFloat->new('1'. ('0' x $lx));
607
608 # print "first guess: $gs (x $x) scale $scale\n";
58cde26e 609
610 my $diff = $e;
611 my $y = $x->copy();
612 my $two = Math::BigFloat->new(2);
613 $x = Math::BigFloat->new($x) if ref($x) ne $class; # promote BigInts
614 # $scale = 2;
615 while ($diff >= $e)
616 {
58cde26e 617 return $x->bnan() if $gs->is_zero();
0716bf9b 618 $r = $y->copy(); $r->bdiv($gs,$scale);
58cde26e 619 $x = ($r + $gs);
0716bf9b 620 $x->bdiv($two,$scale);
58cde26e 621 $diff = $x->copy()->bsub($gs)->babs();
58cde26e 622 $gs = $x->copy();
a0d0e21e 623 }
0716bf9b 624 $x->round($a,$p,$r);
58cde26e 625 }
626
627sub bpow
628 {
629 # (BFLOAT or num_str, BFLOAT or num_str) return BFLOAT
630 # compute power of two numbers, second arg is used as integer
631 # modifies first argument
632
633 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
634
0716bf9b 635 return $x if $x->{sign} =~ /^[+-]inf$/;
58cde26e 636 return $x->bnan() if $x->{sign} eq $nan || $y->{sign} eq $nan;
0716bf9b 637 return $x->bzero()->binc() if $y->is_zero();
58cde26e 638 return $x if $x->is_one() || $y->is_one();
639 my $y1 = $y->as_number(); # make bigint
640 if ($x == -1)
641 {
642 # if $x == -1 and odd/even y => +1/-1 because +-1 ^ (+-1) => +-1
0716bf9b 643 return $y1->is_odd() ? $x : $x->babs(1);
288d023a 644 }
58cde26e 645 return $x if $x->is_zero() && $y->{sign} eq '+'; # 0**y => 0 (if not y <= 0)
646 # 0 ** -y => 1 / (0 ** y) => / 0!
647 return $x->bnan() if $x->is_zero() && $y->{sign} eq '-';
648
649 # calculate $x->{_m} ** $y and $x->{_e} * $y separately (faster)
650 $y1->babs();
651 $x->{_m}->bpow($y1);
652 $x->{_e}->bmul($y1);
653 $x->{sign} = $nan if $x->{_m}->{sign} eq $nan || $x->{_e}->{sign} eq $nan;
654 $x->bnorm();
655 if ($y->{sign} eq '-')
656 {
657 # modify $x in place!
0716bf9b 658 my $z = $x->copy(); $x->bzero()->binc();
58cde26e 659 return $x->bdiv($z,$a,$p,$r); # round in one go (might ignore y's A!)
a0d0e21e 660 }
58cde26e 661 return $x->round($a,$p,$r,$y);
662 }
663
664###############################################################################
665# rounding functions
666
667sub bfround
668 {
669 # precision: round to the $Nth digit left (+$n) or right (-$n) from the '.'
670 # $n == 0 means round to integer
671 # expects and returns normalized numbers!
672 my $x = shift; $x = $class->new($x) unless ref $x;
a0d0e21e 673
58cde26e 674 return $x if $x->modify('bfround');
675
676 my ($scale,$mode) = $x->_scale_p($precision,$rnd_mode,@_);
677 return $x if !defined $scale; # no-op
678
679 # print "MBF bfround $x to scale $scale mode $mode\n";
680 return $x if $x->is_nan() or $x->is_zero();
681
682 if ($scale < 0)
683 {
684 # print "bfround scale $scale e $x->{_e}\n";
685 # round right from the '.'
686 return $x if $x->{_e} >= 0; # nothing to round
687 $scale = -$scale; # positive for simplicity
688 my $len = $x->{_m}->length(); # length of mantissa
689 my $dad = -$x->{_e}; # digits after dot
690 my $zad = 0; # zeros after dot
691 $zad = -$len-$x->{_e} if ($x->{_e} < -$len);# for 0.00..00xxx style
692 # print "scale $scale dad $dad zad $zad len $len\n";
693
694 # number bsstr len zad dad
695 # 0.123 123e-3 3 0 3
696 # 0.0123 123e-4 3 1 4
697 # 0.001 1e-3 1 2 3
698 # 1.23 123e-2 3 0 2
699 # 1.2345 12345e-4 5 0 4
700
701 # do not round after/right of the $dad
702 return $x if $scale > $dad; # 0.123, scale >= 3 => exit
703
704 # round to zero if rounding inside the $zad, but not for last zero like:
705 # 0.0065, scale -2, round last '0' with following '65' (scale == zad case)
706 if ($scale < $zad)
707 {
708 $x->{_m} = Math::BigInt->new(0);
709 $x->{_e} = Math::BigInt->new(1);
710 $x->{sign} = '+';
711 return $x;
712 }
713 if ($scale == $zad) # for 0.006, scale -2 and trunc
714 {
715 $scale = -$len;
716 }
717 else
718 {
719 # adjust round-point to be inside mantissa
720 if ($zad != 0)
721 {
722 $scale = $scale-$zad;
723 }
724 else
725 {
726 my $dbd = $len - $dad; $dbd = 0 if $dbd < 0; # digits before dot
727 $scale = $dbd+$scale;
728 }
729 }
730 # print "round to $x->{_m} to $scale\n";
a0d0e21e 731 }
58cde26e 732 else
733 {
734 # 123 => 100 means length(123) = 3 - $scale (2) => 1
a5f75d66 735
58cde26e 736 # calculate digits before dot
737 my $dbt = $x->{_m}->length(); $dbt += $x->{_e} if $x->{_e}->sign() eq '-';
738 if (($scale > $dbt) && ($dbt < 0))
739 {
740 # if not enough digits before dot, round to zero
741 $x->{_m} = Math::BigInt->new(0);
742 $x->{_e} = Math::BigInt->new(1);
743 $x->{sign} = '+';
744 return $x;
745 }
746 if (($scale >= 0) && ($dbt == 0))
747 {
748 # 0.49->bfround(1): scale == 1, dbt == 0: => 0.0
749 # 0.51->bfround(0): scale == 0, dbt == 0: => 1.0
750 # 0.5->bfround(0): scale == 0, dbt == 0: => 0
751 # 0.05->bfround(0): scale == 0, dbt == 0: => 0
752 # print "$scale $dbt $x->{_m}\n";
753 $scale = -$x->{_m}->length();
754 }
755 elsif ($dbt > 0)
756 {
757 # correct by subtracting scale
758 $scale = $dbt - $scale;
759 }
760 else
761 {
762 $scale = $x->{_m}->length() - $scale;
763 }
a0d0e21e 764 }
58cde26e 765 #print "using $scale for $x->{_m} with '$mode'\n";
766 # pass sign to bround for '+inf' and '-inf' rounding modes
767 $x->{_m}->{sign} = $x->{sign};
768 $x->{_m}->bround($scale,$mode);
769 $x->{_m}->{sign} = '+'; # fix sign back
770 $x->bnorm();
771 }
772
773sub bround
774 {
775 # accuracy: preserve $N digits, and overwrite the rest with 0's
776 my $x = shift; $x = $class->new($x) unless ref $x;
777 my ($scale,$mode) = $x->_scale_a($accuracy,$rnd_mode,@_);
778 return $x if !defined $scale; # no-op
779
780 return $x if $x->modify('bround');
781
782 # print "bround $scale $mode\n";
783 # 0 => return all digits, scale < 0 makes no sense
784 return $x if ($scale <= 0);
785 return $x if $x->is_nan() or $x->is_zero(); # never round a 0
786
787 # if $e longer than $m, we have 0.0000xxxyyy style number, and must
788 # subtract the delta from scale, to simulate keeping the zeros
789 # -5 +5 => 1; -10 +5 => -4
790 my $delta = $x->{_e} + $x->{_m}->length() + 1;
791 # removed by tlr, since causes problems with fraction tests:
792 # $scale += $delta if $delta < 0;
793
794 # if we should keep more digits than the mantissa has, do nothing
795 return $x if $x->{_m}->length() <= $scale;
f216259d 796
58cde26e 797 # pass sign to bround for '+inf' and '-inf' rounding modes
798 $x->{_m}->{sign} = $x->{sign};
799 $x->{_m}->bround($scale,$mode); # round mantissa
800 $x->{_m}->{sign} = '+'; # fix sign back
801 return $x->bnorm(); # del trailing zeros gen. by bround()
802 }
803
804sub bfloor
805 {
806 # return integer less or equal then $x
807 my ($self,$x,$a,$p,$r) = objectify(1,@_);
808
809 return $x if $x->modify('bfloor');
810
811 return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
812
813 # if $x has digits after dot
814 if ($x->{_e}->{sign} eq '-')
815 {
816 $x->{_m}->brsft(-$x->{_e},10);
817 $x->{_e}->bzero();
818 $x-- if $x->{sign} eq '-';
f216259d 819 }
58cde26e 820 return $x->round($a,$p,$r);
821 }
288d023a 822
58cde26e 823sub bceil
824 {
825 # return integer greater or equal then $x
826 my ($self,$x,$a,$p,$r) = objectify(1,@_);
827
828 return $x if $x->modify('bceil');
829 return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
830
831 # if $x has digits after dot
832 if ($x->{_e}->{sign} eq '-')
833 {
834 $x->{_m}->brsft(-$x->{_e},10);
835 $x->{_e}->bzero();
836 $x++ if $x->{sign} eq '+';
a0d0e21e 837 }
58cde26e 838 return $x->round($a,$p,$r);
839 }
840
841###############################################################################
a5f75d66 842
58cde26e 843sub DESTROY
844 {
845 # going trough AUTOLOAD for every DESTROY is costly, so avoid it by empty sub
846 }
847
848sub AUTOLOAD
849 {
850 # make fxxx and bxxx work
851 # my $self = $_[0];
852 my $name = $AUTOLOAD;
853
854 $name =~ s/.*:://; # split package
855 #print "$name\n";
856 if (!method_valid($name))
857 {
858 #no strict 'refs';
859 ## try one level up
860 #&{$class."::SUPER->$name"}(@_);
861 # delayed load of Carp and avoid recursion
862 require Carp;
863 Carp::croak ("Can't call $class\-\>$name, not a valid method");
a0d0e21e 864 }
58cde26e 865 no strict 'refs';
866 my $bname = $name; $bname =~ s/^f/b/;
867 *{$class."\:\:$name"} = \&$bname;
868 &$bname; # uses @_
869 }
870
871sub exponent
872 {
873 # return a copy of the exponent
874 my $self = shift;
875 $self = $class->new($self) unless ref $self;
876
877 return bnan() if $self->is_nan();
878 return $self->{_e}->copy();
879 }
880
881sub mantissa
882 {
883 # return a copy of the mantissa
884 my $self = shift;
885 $self = $class->new($self) unless ref $self;
886
887 return bnan() if $self->is_nan();
888 my $m = $self->{_m}->copy(); # faster than going via bstr()
889 $m->bneg() if $self->{sign} eq '-';
890
891 return $m;
892 }
893
894sub parts
895 {
896 # return a copy of both the exponent and the mantissa
897 my $self = shift;
898 $self = $class->new($self) unless ref $self;
899
900 return (bnan(),bnan()) if $self->is_nan();
901 my $m = $self->{_m}->copy(); # faster than going via bstr()
902 $m->bneg() if $self->{sign} eq '-';
903 return ($m,$self->{_e}->copy());
904 }
905
906##############################################################################
907# private stuff (internal use only)
908
909sub _one
910 {
911 # internal speedup, set argument to 1, or create a +/- 1
0716bf9b 912 my $self = shift; $self = ref($self) if ref($self);
913 my $x = {}; bless $x, $self;
914 $x->{_m} = Math::BigInt->new(1);
915 $x->{_e} = Math::BigInt->new(0);
58cde26e 916 $x->{sign} = shift || '+';
917 return $x;
918 }
919
920sub import
921 {
922 my $self = shift;
923 #print "import $self\n";
924 for ( my $i = 0; $i < @_ ; $i++ )
925 {
926 if ( $_[$i] eq ':constant' )
927 {
928 # this rest causes overlord er load to step in
929 # print "overload @_\n";
930 overload::constant float => sub { $self->new(shift); };
931 splice @_, $i, 1; last;
932 }
933 }
934 # any non :constant stuff is handled by our parent, Exporter
935 # even if @_ is empty, to give it a chance
936 #$self->SUPER::import(@_); # does not work (would call MBI)
937 $self->export_to_level(1,$self,@_); # need this instead
938 }
939
940sub bnorm
941 {
942 # adjust m and e so that m is smallest possible
943 # round number according to accuracy and precision settings
944 my $x = shift;
945
0716bf9b 946 return $x if $x->{sign} !~ /^[+-]$/; # inf, nan etc
58cde26e 947
948 my $zeros = $x->{_m}->_trailing_zeros(); # correct for trailing zeros
949 if ($zeros != 0)
950 {
951 $x->{_m}->brsft($zeros,10); $x->{_e} += $zeros;
952 }
953 # for something like 0Ey, set y to 1
954 $x->{_e}->bzero()->binc() if $x->{_m}->is_zero();
0716bf9b 955 $x->{_m}->{_f} = MB_NEVER_ROUND;
956 $x->{_e}->{_f} = MB_NEVER_ROUND;
957 return $x; # MBI bnorm is no-op
58cde26e 958 }
959
960##############################################################################
961# internal calculation routines
962
963sub as_number
964 {
965 # return a bigint representation of this BigFloat number
966 my ($self,$x) = objectify(1,@_);
967
968 my $z;
969 if ($x->{_e}->is_zero())
970 {
971 $z = $x->{_m}->copy();
972 $z->{sign} = $x->{sign};
973 return $z;
974 }
0716bf9b 975 $z = $x->{_m}->copy();
58cde26e 976 if ($x->{_e} < 0)
977 {
0716bf9b 978 $z->brsft(-$x->{_e},10);
979 }
980 else
981 {
982 $z->blsft($x->{_e},10);
58cde26e 983 }
58cde26e 984 $z->{sign} = $x->{sign};
985 return $z;
986 }
987
988sub length
989 {
990 my $x = shift; $x = $class->new($x) unless ref $x;
991
992 my $len = $x->{_m}->length();
993 $len += $x->{_e} if $x->{_e}->sign() eq '+';
994 if (wantarray())
995 {
996 my $t = Math::BigInt::bzero();
997 $t = $x->{_e}->copy()->babs() if $x->{_e}->sign() eq '-';
998 return ($len,$t);
999 }
1000 return $len;
1001 }
a0d0e21e 1002
10031;
a5f75d66 1004__END__
1005
1006=head1 NAME
1007
58cde26e 1008Math::BigFloat - Arbitrary size floating point math package
a5f75d66 1009
1010=head1 SYNOPSIS
1011
a2008d6d 1012 use Math::BigFloat;
58cde26e 1013
1014 # Number creation
1015 $x = Math::BigInt->new($str); # defaults to 0
1016 $nan = Math::BigInt->bnan(); # create a NotANumber
1017 $zero = Math::BigInt->bzero();# create a "+0"
1018
1019 # Testing
1020 $x->is_zero(); # return whether arg is zero or not
0716bf9b 1021 $x->is_nan(); # return whether arg is NaN or not
1022 $x->is_one(); # true if arg is +1
1023 $x->is_one('-'); # true if arg is -1
1024 $x->is_odd(); # true if odd, false for even
1025 $x->is_even(); # true if even, false for odd
1026 $x->is_positive(); # true if >= 0
1027 $x->is_negative(); # true if < 0
1028 $x->is_inf(sign) # true if +inf or -inf (sign default '+')
58cde26e 1029 $x->bcmp($y); # compare numbers (undef,<0,=0,>0)
1030 $x->bacmp($y); # compare absolutely (undef,<0,=0,>0)
1031 $x->sign(); # return the sign, either +,- or NaN
1032
1033 # The following all modify their first argument:
1034
1035 # set
1036 $x->bzero(); # set $i to 0
1037 $x->bnan(); # set $i to NaN
1038
1039 $x->bneg(); # negation
1040 $x->babs(); # absolute value
1041 $x->bnorm(); # normalize (no-op)
1042 $x->bnot(); # two's complement (bit wise not)
1043 $x->binc(); # increment x by 1
1044 $x->bdec(); # decrement x by 1
1045
1046 $x->badd($y); # addition (add $y to $x)
1047 $x->bsub($y); # subtraction (subtract $y from $x)
1048 $x->bmul($y); # multiplication (multiply $x by $y)
1049 $x->bdiv($y); # divide, set $i to quotient
1050 # return (quo,rem) or quo if scalar
1051
1052 $x->bmod($y); # modulus
1053 $x->bpow($y); # power of arguments (a**b)
1054 $x->blsft($y); # left shift
1055 $x->brsft($y); # right shift
1056 # return (quo,rem) or quo if scalar
1057
1058 $x->band($y); # bit-wise and
1059 $x->bior($y); # bit-wise inclusive or
1060 $x->bxor($y); # bit-wise exclusive or
1061 $x->bnot(); # bit-wise not (two's complement)
1062
1063 $x->bround($N); # accuracy: preserver $N digits
1064 $x->bfround($N); # precision: round to the $Nth digit
1065
1066 # The following do not modify their arguments:
1067
1068 bgcd(@values); # greatest common divisor
1069 blcm(@values); # lowest common multiplicator
1070
1071 $x->bstr(); # return string
1072 $x->bsstr(); # return string in scientific notation
1073
1074 $x->exponent(); # return exponent as BigInt
1075 $x->mantissa(); # return mantissa as BigInt
1076 $x->parts(); # return (mantissa,exponent) as BigInt
1077
1078 $x->length(); # number of digits (w/o sign and '.')
1079 ($l,$f) = $x->length(); # number of digits, and length of fraction
a5f75d66 1080
1081=head1 DESCRIPTION
1082
58cde26e 1083All operators (inlcuding basic math operations) are overloaded if you
1084declare your big floating point numbers as
a5f75d66 1085
58cde26e 1086 $i = new Math::BigFloat '12_3.456_789_123_456_789E-2';
1087
1088Operations with overloaded operators preserve the arguments, which is
1089exactly what you expect.
1090
1091=head2 Canonical notation
1092
1093Input to these routines are either BigFloat objects, or strings of the
1094following four forms:
a5f75d66 1095
1096=over 2
1097
58cde26e 1098=item *
1099
1100C</^[+-]\d+$/>
a5f75d66 1101
58cde26e 1102=item *
a5f75d66 1103
58cde26e 1104C</^[+-]\d+\.\d*$/>
a5f75d66 1105
58cde26e 1106=item *
a5f75d66 1107
58cde26e 1108C</^[+-]\d+E[+-]?\d+$/>
a5f75d66 1109
58cde26e 1110=item *
a5f75d66 1111
58cde26e 1112C</^[+-]\d*\.\d+E[+-]?\d+$/>
5d7098d5 1113
58cde26e 1114=back
1115
1116all with optional leading and trailing zeros and/or spaces. Additonally,
1117numbers are allowed to have an underscore between any two digits.
1118
1119Empty strings as well as other illegal numbers results in 'NaN'.
1120
1121bnorm() on a BigFloat object is now effectively a no-op, since the numbers
1122are always stored in normalized form. On a string, it creates a BigFloat
1123object.
1124
1125=head2 Output
1126
1127Output values are BigFloat objects (normalized), except for bstr() and bsstr().
1128
1129The string output will always have leading and trailing zeros stripped and drop
1130a plus sign. C<bstr()> will give you always the form with a decimal point,
1131while C<bsstr()> (for scientific) gives you the scientific notation.
1132
1133 Input bstr() bsstr()
1134 '-0' '0' '0E1'
1135 ' -123 123 123' '-123123123' '-123123123E0'
1136 '00.0123' '0.0123' '123E-4'
1137 '123.45E-2' '1.2345' '12345E-4'
1138 '10E+3' '10000' '1E4'
1139
1140Some routines (C<is_odd()>, C<is_even()>, C<is_zero()>, C<is_one()>,
1141C<is_nan()>) return true or false, while others (C<bcmp()>, C<bacmp()>)
1142return either undef, <0, 0 or >0 and are suited for sort.
1143
1144Actual math is done by using BigInts to represent the mantissa and exponent.
1145The sign C</^[+-]$/> is stored separately. The string 'NaN' is used to
1146represent the result when input arguments are not numbers, as well as
1147the result of dividing by zero.
1148
1149=head2 C<mantissa()>, C<exponent()> and C<parts()>
1150
1151C<mantissa()> and C<exponent()> return the said parts of the BigFloat
1152as BigInts such that:
1153
1154 $m = $x->mantissa();
1155 $e = $x->exponent();
1156 $y = $m * ( 10 ** $e );
1157 print "ok\n" if $x == $y;
1158
1159C<< ($m,$e) = $x->parts(); >> is just a shortcut giving you both of them.
1160
1161A zero is represented and returned as C<0E1>, B<not> C<0E0> (after Knuth).
1162
1163Currently the mantissa is reduced as much as possible, favouring higher
1164exponents over lower ones (e.g. returning 1e7 instead of 10e6 or 10000000e0).
1165This might change in the future, so do not depend on it.
1166
1167=head2 Accuracy vs. Precision
1168
1169See also: L<Rounding|Rounding>.
1170
1171Math::BigFloat supports both precision and accuracy. (here should follow
1172a short description of both).
5d7098d5 1173
58cde26e 1174Precision: digits after the '.', laber, schwad
1175Accuracy: Significant digits blah blah
5d7098d5 1176
58cde26e 1177Since things like sqrt(2) or 1/3 must presented with a limited precision lest
1178a operation consumes all resources, each operation produces no more than
1179C<Math::BigFloat::precision()> digits.
1180
1181In case the result of one operation has more precision than specified,
1182it is rounded. The rounding mode taken is either the default mode, or the one
1183supplied to the operation after the I<scale>:
1184
1185 $x = Math::BigFloat->new(2);
1186 Math::BigFloat::precision(5); # 5 digits max
1187 $y = $x->copy()->bdiv(3); # will give 0.66666
1188 $y = $x->copy()->bdiv(3,6); # will give 0.666666
1189 $y = $x->copy()->bdiv(3,6,'odd'); # will give 0.666667
1190 Math::BigFloat::round_mode('zero');
1191 $y = $x->copy()->bdiv(3,6); # will give 0.666666
1192
1193=head2 Rounding
1194
1195=over 2
1196
5dc6f178 1197=item ffround ( +$scale )
58cde26e 1198
0716bf9b 1199Rounds to the $scale'th place left from the '.', counting from the dot.
1200The first digit is numbered 1.
58cde26e 1201
5dc6f178 1202=item ffround ( -$scale )
58cde26e 1203
0716bf9b 1204Rounds to the $scale'th place right from the '.', counting from the dot.
58cde26e 1205
5dc6f178 1206=item ffround ( 0 )
1207
0716bf9b 1208Rounds to an integer.
5dc6f178 1209
1210=item fround ( +$scale )
1211
0716bf9b 1212Preserves accuracy to $scale digits from the left (aka significant digits)
1213and pads the rest with zeros. If the number is between 1 and -1, the
1214significant digits count from the first non-zero after the '.'
5dc6f178 1215
1216=item fround ( -$scale ) and fround ( 0 )
1217
0716bf9b 1218These are effetively no-ops.
5d7098d5 1219
a5f75d66 1220=back
1221
0716bf9b 1222All rounding functions take as a second parameter a rounding mode from one of
1223the following: 'even', 'odd', '+inf', '-inf', 'zero' or 'trunc'.
58cde26e 1224
1225The default rounding mode is 'even'. By using
0716bf9b 1226C<< Math::BigFloat::round_mode($rnd_mode); >> you can get and set the default
1227mode for subsequent rounding. The usage of C<$Math::BigFloat::$rnd_mode> is
1228no longer supported.
b22b3e31 1229The second parameter to the round functions then overrides the default
0716bf9b 1230temporarily.
58cde26e 1231
1232The C<< as_number() >> function returns a BigInt from a Math::BigFloat. It uses
1233'trunc' as rounding mode to make it equivalent to:
1234
1235 $x = 2.5;
1236 $y = int($x) + 2;
1237
1238You can override this by passing the desired rounding mode as parameter to
1239C<as_number()>:
1240
1241 $x = Math::BigFloat->new(2.5);
1242 $y = $x->as_number('odd'); # $y = 3
1243
1244=head1 EXAMPLES
1245
1246 use Math::BigFloat qw(bstr bint);
1247 # not ready yet
1248 $x = bstr("1234") # string "1234"
1249 $x = "$x"; # same as bstr()
1250 $x = bneg("1234") # BigFloat "-1234"
1251 $x = Math::BigFloat->bneg("1234"); # BigFloat "1234"
1252 $x = Math::BigFloat->babs("-12345"); # BigFloat "12345"
1253 $x = Math::BigFloat->bnorm("-0 00"); # BigFloat "0"
1254 $x = bint(1) + bint(2); # BigFloat "3"
1255 $x = bint(1) + "2"; # ditto (auto-BigFloatify of "2")
1256 $x = bint(1); # BigFloat "1"
1257 $x = $x + 5 / 2; # BigFloat "3"
1258 $x = $x ** 3; # BigFloat "27"
1259 $x *= 2; # BigFloat "54"
1260 $x = new Math::BigFloat; # BigFloat "0"
1261 $x--; # BigFloat "-1"
1262
1263=head1 Autocreating constants
1264
1265After C<use Math::BigFloat ':constant'> all the floating point constants
1266in the given scope are converted to C<Math::BigFloat>. This conversion
1267happens at compile time.
1268
1269In particular
1270
1271 perl -MMath::BigFloat=:constant -e 'print 2E-100,"\n"'
1272
1273prints the value of C<2E-100>. Note that without conversion of
1274constants the expression 2E-100 will be calculated as normal floating point
1275number.
1276
1277=head1 PERFORMANCE
1278
1279Greatly enhanced ;o)
1280SectionNotReadyYet.
1281
a5f75d66 1282=head1 BUGS
1283
58cde26e 1284=over 2
1285
1286=item *
1287
1288The following does not work yet:
1289
1290 $m = $x->mantissa();
1291 $e = $x->exponent();
1292 $y = $m * ( 10 ** $e );
1293 print "ok\n" if $x == $y;
1294
1295=item *
1296
1297There is no fmod() function yet.
1298
1299=back
1300
1301=head1 CAVEAT
1302
1303=over 1
1304
1305=item stringify, bstr()
1306
1307Both stringify and bstr() now drop the leading '+'. The old code would return
1308'+1.23', the new returns '1.23'. See the documentation in L<Math::BigInt> for
1309reasoning and details.
1310
1311=item bdiv
1312
1313The following will probably not do what you expect:
1314
1315 print $c->bdiv(123.456),"\n";
1316
1317It prints both quotient and reminder since print works in list context. Also,
1318bdiv() will modify $c, so be carefull. You probably want to use
1319
1320 print $c / 123.456,"\n";
1321 print scalar $c->bdiv(123.456),"\n"; # or if you want to modify $c
1322
1323instead.
1324
1325=item Modifying and =
1326
1327Beware of:
1328
1329 $x = Math::BigFloat->new(5);
1330 $y = $x;
1331
1332It will not do what you think, e.g. making a copy of $x. Instead it just makes
1333a second reference to the B<same> object and stores it in $y. Thus anything
1334that modifies $x will modify $y, and vice versa.
1335
1336 $x->bmul(2);
1337 print "$x, $y\n"; # prints '10, 10'
1338
1339If you want a true copy of $x, use:
1340
1341 $y = $x->copy();
1342
1343See also the documentation in L<overload> regarding C<=>.
1344
1345=item bpow
1346
1347C<bpow()> now modifies the first argument, unlike the old code which left
1348it alone and only returned the result. This is to be consistent with
1349C<badd()> etc. The first will modify $x, the second one won't:
1350
1351 print bpow($x,$i),"\n"; # modify $x
1352 print $x->bpow($i),"\n"; # ditto
1353 print $x ** $i,"\n"; # leave $x alone
1354
1355=back
1356
1357=head1 LICENSE
a5f75d66 1358
58cde26e 1359This program is free software; you may redistribute it and/or modify it under
1360the same terms as Perl itself.
5d7098d5 1361
58cde26e 1362=head1 AUTHORS
5d7098d5 1363
58cde26e 1364Mark Biggar, overloaded interface by Ilya Zakharevich.
1365Completely rewritten by Tels http://bloodgate.com in 2001.
a5f75d66 1366
a5f75d66 1367=cut