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