Math::BigInt v1.87 take 10
[p5sagit/p5-mst-13.2.git] / lib / Math / BigInt.pm
index ac351db..134a4b7 100644 (file)
@@ -16,9 +16,9 @@ package Math::BigInt;
 # underlying lib might change the reference!
 
 my $class = "Math::BigInt";
-use 5.005;
+use 5.006002;
 
-$VERSION = '1.79';
+$VERSION = '1.87';
 
 @ISA = qw(Exporter);
 @EXPORT_OK = qw(objectify bgcd blcm); 
@@ -62,19 +62,27 @@ use overload
 # not supported by Perl yet
 '..'   =>      \&_pointpoint,
 
-# we might need '==' and '!=' to get things like "NaN == NaN" right
-'<=>'  =>      sub { $_[2] ?
+'<=>'  =>      sub { my $rc = $_[2] ?
                       ref($_[0])->bcmp($_[1],$_[0]) : 
-                      $_[0]->bcmp($_[1]); },
+                      $_[0]->bcmp($_[1]); 
+                     $rc = 1 unless defined $rc;
+                     $rc <=> 0;
+               },
+# we need '>=' to get things like "1 >= NaN" right:
+'>='   =>      sub { my $rc = $_[2] ?
+                      ref($_[0])->bcmp($_[1],$_[0]) : 
+                      $_[0]->bcmp($_[1]);
+                     # if there was a NaN involved, return false
+                     return '' unless defined $rc;
+                     $rc >= 0;
+               },
 'cmp'  =>      sub {
          $_[2] ? 
                "$_[1]" cmp $_[0]->bstr() :
                $_[0]->bstr() cmp "$_[1]" },
 
-# make cos()/sin()/exp() "work" with BigInt's or subclasses
-'cos'  =>      sub { cos($_[0]->numify()) }, 
-'sin'  =>      sub { sin($_[0]->numify()) }, 
-'exp'  =>      sub { exp($_[0]->numify()) }, 
+'cos'  =>      sub { $_[0]->copy->bcos(); }, 
+'sin'  =>      sub { $_[0]->copy->bsin(); }, 
 'atan2'        =>      sub { $_[2] ?
                        atan2($_[1],$_[0]->numify()) :
                        atan2($_[0]->numify(),$_[1]) },
@@ -83,7 +91,9 @@ use overload
 #'hex' =>      sub { print "hex"; $_[0]; }, 
 #'oct' =>      sub { print "oct"; $_[0]; }, 
 
-'log'  =>      sub { $_[0]->copy()->blog($_[1]); }, 
+# log(N) is log(N, e), where e is Euler's number
+'log'  =>      sub { $_[0]->copy()->blog($_[1], undef); }, 
+'exp'  =>      sub { $_[0]->copy()->bexp($_[1]); }, 
 'int'  =>      sub { $_[0]->copy(); }, 
 'neg'  =>      sub { $_[0]->copy()->bneg(); }, 
 'abs'  =>      sub { $_[0]->copy()->babs(); },
@@ -364,7 +374,7 @@ sub config
   my $class = shift || 'Math::BigInt';
 
   no strict 'refs';
-  if (@_ > 0)
+  if (@_ > 1 || (@_ == 1 && (ref($_[0]) eq 'HASH')))
     {
     # try to set given options as arguments from hash
 
@@ -417,6 +427,11 @@ sub config
     {
     $cfg->{$key} = ${"${class}::$key"};
     };
+  if (@_ == 1 && (ref($_[0]) ne 'HASH'))
+    {
+    # calls of the style config('lib') return just this value
+    return $cfg->{$_[0]};
+    }
   $cfg;
   }
 
@@ -459,25 +474,26 @@ sub _scale_p
 
 sub copy
   {
-  my ($c,$x);
+  # if two arguments, the first one is the class to "swallow" subclasses
   if (@_ > 1)
     {
-    # if two arguments, the first one is the class to "swallow" subclasses
-    ($c,$x) = @_;
-    }
-  else
-    {
-    $x = shift;
-    $c = ref($x);
+    my  $self = bless {
+       sign => $_[1]->{sign}, 
+       value => $CALC->_copy($_[1]->{value}),
+    }, $_[0] if @_ > 1;
+
+    $self->{_a} = $_[1]->{_a} if defined $_[1]->{_a};
+    $self->{_p} = $_[1]->{_p} if defined $_[1]->{_p};
+    return $self;
     }
-  return unless ref($x); # only for objects
 
-  my $self = bless {}, $c;
+  my $self = bless {
+       sign => $_[0]->{sign}, 
+       value => $CALC->_copy($_[0]->{value}),
+       }, ref($_[0]);
 
-  $self->{sign} = $x->{sign};
-  $self->{value} = $CALC->_copy($x->{value});
-  $self->{_a} = $x->{_a} if defined $x->{_a};
-  $self->{_p} = $x->{_p} if defined $x->{_p};
+  $self->{_a} = $_[0]->{_a} if defined $_[0]->{_a};
+  $self->{_p} = $_[0]->{_p} if defined $_[0]->{_p};
   $self;
   }
 
@@ -849,6 +865,10 @@ sub _find_round_parameters
   my $c = ref($self);                          # find out class of argument(s)
   no strict 'refs';
 
+  # convert to normal scalar for speed and correctness in inner parts
+  $a = $a->can('numify') ? $a->numify() : "$a" if defined $a && ref($a);
+  $p = $p->can('numify') ? $p->numify() : "$p" if defined $p && ref($p);
+
   # now pick $a or $p, but only if we have got "arguments"
   if (!defined $a)
     {
@@ -1134,6 +1154,7 @@ sub bsub
   
   # set up parameters
   my ($self,$x,$y,@r) = (ref($_[0]),@_);
+
   # objectify is costly, so avoid it
   if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
     {
@@ -1225,9 +1246,11 @@ sub blog
     {
     ($self,$x,$base,@r) = objectify(1,ref($x),@_);
     }
-  
+
   return $x if $x->modify('blog');
 
+  $base = $self->new($base) if defined $base && !ref $base;
+
   # inf, -inf, NaN, <0 => NaN
   return $x->bnan()
    if $x->{sign} ne '+' || (defined $base && $base->{sign} ne '+');
@@ -1235,12 +1258,107 @@ sub blog
   return $upgrade->blog($upgrade->new($x),$base,@r) if 
     defined $upgrade;
 
+  # fix for bug #24969:
+  # the default base is e (Euler's number) which is not an integer
+  if (!defined $base)
+    {
+    require Math::BigFloat;
+    my $u = Math::BigFloat->blog(Math::BigFloat->new($x))->as_int();
+    # modify $x in place
+    $x->{value} = $u->{value};
+    $x->{sign} = $u->{sign};
+    return $x;
+    }
+  
   my ($rc,$exact) = $CALC->_log_int($x->{value},$base->{value});
   return $x->bnan() unless defined $rc;                # not possible to take log?
   $x->{value} = $rc;
   $x->round(@r);
   }
 
+sub bnok
+  {
+  # Calculate n over k (binomial coefficient or "choose" function) as integer.
+  # set up parameters
+  my ($self,$x,$y,@r) = (ref($_[0]),@_);
+
+  # objectify is costly, so avoid it
+  if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
+    {
+    ($self,$x,$y,@r) = objectify(2,@_);
+    }
+
+  return $x if $x->modify('bnok');
+  return $x->bnan() if $x->{sign} eq 'NaN' || $y->{sign} eq 'NaN';
+  return $x->binf() if $x->{sign} eq '+inf';
+
+  # k > n or k < 0 => 0
+  my $cmp = $x->bacmp($y);
+  return $x->bzero() if $cmp < 0 || $y->{sign} =~ /^-/;
+  # k == n => 1
+  return $x->bone(@r) if $cmp == 0;
+
+  if ($CALC->can('_nok'))
+    {
+    $x->{value} = $CALC->_nok($x->{value},$y->{value});
+    }
+  else
+    {
+    # ( 7 )    7!          7*6*5 * 4*3*2*1   7 * 6 * 5
+    # ( - ) = --------- =  --------------- = ---------
+    # ( 3 )   3! (7-3)!    3*2*1 * 4*3*2*1   3 * 2 * 1 
+
+    # compute n - k + 2 (so we start with 5 in the example above)
+    my $z = $x - $y;
+    if (!$z->is_one())
+      {
+      $z->binc();
+      my $r = $z->copy(); $z->binc();
+      my $d = $self->new(2);
+      while ($z->bacmp($x) <= 0)               # f < x ?
+        {
+        $r->bmul($z); $r->bdiv($d);
+        $z->binc(); $d->binc();
+        }
+      $x->{value} = $r->{value}; $x->{sign} = '+';
+      }
+    else { $x->bone(); }
+    }
+  $x->round(@r);
+  }
+
+sub bexp
+  {
+  # Calculate e ** $x (Euler's number to the power of X), truncated to
+  # an integer value.
+  my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
+  return $x if $x->modify('bexp');
+
+  # inf, -inf, NaN, <0 => NaN
+  return $x->bnan() if $x->{sign} eq 'NaN';
+  return $x->bone() if $x->is_zero();
+  return $x if $x->{sign} eq '+inf';
+  return $x->bzero() if $x->{sign} eq '-inf';
+
+  my $u;
+  {
+    # run through Math::BigFloat unless told otherwise
+    require Math::BigFloat unless defined $upgrade;
+    local $upgrade = 'Math::BigFloat' unless defined $upgrade;
+    # calculate result, truncate it to integer
+    $u = $upgrade->bexp($upgrade->new($x),@r);
+  }
+
+  if (!defined $upgrade)
+    {
+    $u = $u->as_int();
+    # modify $x in place
+    $x->{value} = $u->{value};
+    $x->round(@r);
+    }
+  else { $x = $u; }
+  }
+
 sub blcm 
   { 
   # (BINT or num_str, BINT or num_str) return BINT
@@ -1394,7 +1512,7 @@ sub is_int
 
 sub bmul 
   { 
-  # multiply two numbers -- stolen from Knuth Vol 2 pg 233
+  # multiply the first number by the second numbers
   # (BINT or num_str, BINT or num_str) return BINT
 
   # set up parameters
@@ -1404,7 +1522,7 @@ sub bmul
     {
     ($self,$x,$y,@r) = objectify(2,@_);
     }
-  
+
   return $x if $x->modify('bmul');
 
   return $x->bnan() if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
@@ -1434,6 +1552,82 @@ sub bmul
   $x->round(@r);
   }
 
+sub bmuladd
+  { 
+  # multiply two numbers and then add the third to the result
+  # (BINT or num_str, BINT or num_str, BINT or num_str) return BINT
+
+  # set up parameters
+  my ($self,$x,$y,$z,@r) = (ref($_[0]),@_);
+  # objectify is costly, so avoid it
+  if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
+    {
+    ($self,$x,$y,$z,@r) = objectify(3,@_);
+    }
+
+  return $x if $x->modify('bmuladd');
+
+  return $x->bnan() if  ($x->{sign} eq $nan) ||
+                       ($y->{sign} eq $nan) ||
+                       ($z->{sign} eq $nan);
+
+  # inf handling of x and y
+  if (($x->{sign} =~ /^[+-]inf$/) || ($y->{sign} =~ /^[+-]inf$/))
+    {
+    return $x->bnan() if $x->is_zero() || $y->is_zero();
+    # result will always be +-inf:
+    # +inf * +/+inf => +inf, -inf * -/-inf => +inf
+    # +inf * -/-inf => -inf, -inf * +/+inf => -inf
+    return $x->binf() if ($x->{sign} =~ /^\+/ && $y->{sign} =~ /^\+/); 
+    return $x->binf() if ($x->{sign} =~ /^-/ && $y->{sign} =~ /^-/); 
+    return $x->binf('-');
+    }
+  # inf handling x*y and z
+  if (($z->{sign} =~ /^[+-]inf$/))
+    {
+    # something +-inf => +-inf
+    $x->{sign} = $z->{sign}, return $x if $z->{sign} =~ /^[+-]inf$/;
+    }
+
+  return $upgrade->bmuladd($x,$upgrade->new($y),$upgrade->new($z),@r)
+   if defined $upgrade && (!$y->isa($self) || !$z->isa($self) || !$x->isa($self));
+  # TODO: what it $y and $z have A or P set?
+  $r[3] = $z;                          # no push here
+
+  $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-'; # +1 * +1 or -1 * -1 => +
+
+  $x->{value} = $CALC->_mul($x->{value},$y->{value});  # do actual math
+  $x->{sign} = '+' if $CALC->_is_zero($x->{value});    # no -0
+
+  my ($sx, $sz) = ( $x->{sign}, $z->{sign} );          # get signs
+
+  if ($sx eq $sz)  
+    {
+    $x->{value} = $CALC->_add($x->{value},$z->{value});        # same sign, abs add
+    }
+  else 
+    {
+    my $a = $CALC->_acmp ($z->{value},$x->{value});    # absolute compare
+    if ($a > 0)                           
+      {
+      $x->{value} = $CALC->_sub($z->{value},$x->{value},1); # abs sub w/ swap
+      $x->{sign} = $sz;
+      } 
+    elsif ($a == 0)
+      {
+      # speedup, if equal, set result to 0
+      $x->{value} = $CALC->_zero();
+      $x->{sign} = '+';
+      }
+    else # a < 0
+      {
+      $x->{value} = $CALC->_sub($x->{value}, $z->{value}); # abs sub
+      }
+    }
+  $x->round(@r);
+  }
+
 sub _div_inf
   {
   # helper function that handles +-inf cases for bdiv()/bmod() to reuse code
@@ -1612,7 +1806,7 @@ sub bmodinv
 sub bmodpow
   {
   # takes a very large number to a very large exponent in a given very
-  # large modulus, quickly, thanks to binary exponentation.  supports
+  # large modulus, quickly, thanks to binary exponentation. Supports
   # negative exponents.
   my ($self,$num,$exp,$mod,@r) = objectify(3,@_);
 
@@ -1802,7 +1996,7 @@ sub brsft
       $bin =~ s/^-0b//;                        # strip '-0b' prefix
       $bin =~ tr/10/01/;               # flip bits
       # now shift
-      if (CORE::length($bin) <= $y)
+      if ($y >= CORE::length($bin))
         {
        $bin = '0';                     # shifting to far right creates -1
                                        # 0, because later increment makes 
@@ -2032,7 +2226,8 @@ sub exponent
     }
   return $self->bone() if $x->is_zero();
 
-  $self->new($x->_trailing_zeros());
+  # 12300 => 2 trailing zeros => exponent is 2
+  $self->new( $CALC->_zeros($x->{value}) );
   }
 
 sub mantissa
@@ -2046,8 +2241,9 @@ sub mantissa
     return $self->new($x->{sign});
     }
   my $m = $x->copy(); delete $m->{_p}; delete $m->{_a};
+
   # that's a bit inefficient:
-  my $zeros = $m->_trailing_zeros();
+  my $zeros = $CALC->_zeros($m->{value});
   $m->brsft($zeros,10) if $zeros != 0;
   $m;
   }
@@ -2320,7 +2516,7 @@ sub objectify
     }
 
   my $up = ${"$a[0]::upgrade"};
-  #print "Now in objectify, my class is today $a[0], count = $count\n";
+  # print STDERR "# Now in objectify, my class is today $a[0], count = $count\n";
   if ($count == 0)
     {
     while (@_)
@@ -2343,7 +2539,7 @@ sub objectify
     while ($count > 0)
       {
       $count--; 
-      $k = shift; 
+      $k = shift;
       if (!ref($k))
         {
         $k = $a[0]->new($k);
@@ -2351,7 +2547,7 @@ sub objectify
       elsif (!defined $up && ref($k) ne $a[0])
        {
        # foreign object, try to convert to integer
-        $k->can('as_number') ?  $k = $k->as_number() : $k = $a[0]->new($k);
+        $k->can('as_number') ? $k = $k->as_number() : $k = $a[0]->new($k);
        }
       push @a,$k;
       }
@@ -2710,6 +2906,86 @@ sub __lcm
   }
 
 ###############################################################################
+# trigonometric functions
+
+sub bpi
+  {
+  # Calculate PI to N digits. Unless upgrading is in effect, returns the
+  # result truncated to an integer, that is, always returns '3'.
+  my ($self,$n) = @_;
+  if (@_ == 1)
+    {
+    # called like Math::BigInt::bpi(10);
+    $n = $self; $self = $class;
+    }
+  $self = ref($self) if ref($self);
+
+  return $upgrade->new($n) if defined $upgrade;
+
+  # hard-wired to "3"
+  $self->new(3);
+  }
+
+sub bcos
+  {
+  # Calculate cosinus(x) to N digits. Unless upgrading is in effect, returns the
+  # result truncated to an integer.
+  my ($self,$x,@r) = ref($_[0]) ? (undef,@_) : objectify(1,@_);
+
+  return $x if $x->modify('bcos');
+
+  return $x->bnan() if $x->{sign} !~ /^[+-]\z/;        # -inf +inf or NaN => NaN
+
+  return $upgrade->new($x)->bcos(@r) if defined $upgrade;
+
+  # calculate the result and truncate it to integer
+  my $t = Math::BigFloat->new($x)->bcos(@r)->as_int();
+
+  $x->bone() if $t->is_one();
+  $x->bzero() if $t->is_zero();
+  $x->round(@r);
+  }
+
+sub bsin
+  {
+  # Calculate sinus(x) to N digits. Unless upgrading is in effect, returns the
+  # result truncated to an integer.
+  my ($self,$x,@r) = ref($_[0]) ? (undef,@_) : objectify(1,@_);
+
+  return $x if $x->modify('bsin');
+
+  return $x->bnan() if $x->{sign} !~ /^[+-]\z/;        # -inf +inf or NaN => NaN
+
+  return $upgrade->new($x)->bsin(@r) if defined $upgrade;
+
+  # calculate the result and truncate it to integer
+  my $t = Math::BigFloat->new($x)->bsin(@r)->as_int();
+
+  $x->bone() if $t->is_one();
+  $x->bzero() if $t->is_zero();
+  $x->round(@r);
+  }
+
+sub batan
+  {
+  # Calculate arcus tangens of x to N digits. Unless upgrading is in effect, returns the
+  # result truncated to an integer.
+  my ($self,$x,@r) = ref($_[0]) ? (undef,@_) : objectify(1,@_);
+
+  return $x if $x->modify('batan');
+
+  return $x->bnan() if $x->{sign} !~ /^[+-]\z/;        # -inf +inf or NaN => NaN
+
+  return $upgrade->new($x)->batan(@r) if defined $upgrade;
+
+  # calculate the result and truncate it to integer
+  my $t = Math::BigFloat->new($x)->batan(@r);
+
+  $x->{value} = $CALC->_new( $x->as_int()->bstr() );
+  $x->round(@r);
+  }
+
+###############################################################################
 # this method returns 0 if the object can be modified, or 1 if not.
 # We use a fast constant sub() here, to avoid costly calls. Subclasses
 # may override it with special code (f.i. Math::BigInt::Constant does so)
@@ -2744,14 +3020,17 @@ Math::BigInt - Arbitrary size integer/float math package
   my $n = 1; my $sign = '-';
 
   # Number creation    
-  $x = Math::BigInt->new($str);                # defaults to 0
-  $y = $x->copy();                     # make a true copy
-  $nan  = Math::BigInt->bnan();        # create a NotANumber
-  $zero = Math::BigInt->bzero();       # create a +0
-  $inf = Math::BigInt->binf();         # create a +inf
-  $inf = Math::BigInt->binf('-');      # create a -inf
-  $one = Math::BigInt->bone();         # create a +1
-  $one = Math::BigInt->bone('-');      # create a -1
+  my $x = Math::BigInt->new($str);     # defaults to 0
+  my $y = $x->copy();                  # make a true copy
+  my $nan  = Math::BigInt->bnan();     # create a NotANumber
+  my $zero = Math::BigInt->bzero();    # create a +0
+  my $inf = Math::BigInt->binf();      # create a +inf
+  my $inf = Math::BigInt->binf('-');   # create a -inf
+  my $one = Math::BigInt->bone();      # create a +1
+  my $mone = Math::BigInt->bone('-');  # create a -1
+
+  my $pi = Math::BigInt->bpi();                # returns '3'
+                                       # see Math::BigFloat::bpi()
 
   $h = Math::BigInt->new('0x123');     # from hexadecimal
   $b = Math::BigInt->new('0b101');     # from binary
@@ -2802,13 +3081,15 @@ Math::BigInt - Arbitrary size integer/float math package
   $x->bdiv($y);                # divide, set $x to quotient
                        # return (quo,rem) or quo if scalar
 
+  $x->bmuladd($y,$z);  # $x = $x * $y + $z
+
   $x->bmod($y);                   # modulus (x % y)
   $x->bmodpow($exp,$mod);  # modular exponentation (($num**$exp) % $mod))
   $x->bmodinv($mod);      # the inverse of $x in the given modulus $mod
 
   $x->bpow($y);                   # power of arguments (x ** y)
-  $x->blsft($y);          # left shift in base 10
-  $x->brsft($y);          # right shift in base 10
+  $x->blsft($y);          # left shift in base 2
+  $x->brsft($y);          # right shift in base 2
                           # returns (quo,rem) or quo if in scalar context
   $x->blsft($y,$n);       # left shift by $y places in base $n
   $x->brsft($y,$n);       # right shift by $y places in base $n
@@ -2823,6 +3104,12 @@ Math::BigInt - Arbitrary size integer/float math package
   $x->broot($y);          # $y'th root of $x (e.g. $y == 3 => cubic root)
   $x->bfac();             # factorial of $x (1*2*3*4*..$x)
 
+  $x->bnok($y);                   # x over y (binomial coefficient n over k)
+
+  $x->blog();             # logarithm of $x to base e (Euler's number)
+  $x->blog($base);        # logarithm of $x to base $base (f.i. 2)
+  $x->bexp();             # calculate e ** $x where e is Euler's number
+  
   $x->round($A,$P,$mode);  # round to accuracy or precision using mode $mode
   $x->bround($n);         # accuracy: preserve $n digits
   $x->bfround($n);        # round to $nth digit, no-op for BigInts
@@ -3258,7 +3545,7 @@ and '-inf', respectively. Does nothing for NaN or zero.
 
        $x->babs();
 
-Set the number to it's absolute value, e.g. change the sign from '-' to '+'
+Set the number to its absolute value, e.g. change the sign from '-' to '+'
 and from '-inf' to '+inf', respectively. Does nothing for NaN or positive
 numbers.
 
@@ -3270,7 +3557,7 @@ numbers.
 
        $x->bnot();                     
 
-Two's complement (bit wise not). This is equivalent to
+Two's complement (bitwise not). This is equivalent to
 
        $x->binc()->bneg();
 
@@ -3296,6 +3583,14 @@ but faster.
 
        $x->bmul($y);                   # multiplication (multiply $x by $y)
 
+=head2 bmuladd()
+
+       $x->bmuladd($y,$z);
+
+Multiply $x by $y, and then add $z to the result,
+
+This method was added in v1.87 of Math::BigInt (June 2007).
+
 =head2 bdiv()
 
        $x->bdiv($y);                   # divide, set $x to quotient
@@ -3339,14 +3634,89 @@ is exactly equivalent to
 
        $x->bpow($y);                   # power of arguments (x ** y)
 
+=head2 blog()
+
+       $x->blog($base, $accuracy);     # logarithm of x to the base $base
+
+If C<$base> is not defined, Euler's number (e) is used:
+
+       print $x->blog(undef, 100);     # log(x) to 100 digits
+
+=head2 bexp()
+
+       $x->bexp($accuracy);            # calculate e ** X
+
+Calculates the expression C<e ** $x> where C<e> is Euler's number.
+
+This method was added in v1.82 of Math::BigInt (April 2007).
+
+See also L<blog()>.
+
+=head2 bnok()
+
+       $x->bnok($y);              # x over y (binomial coefficient n over k)
+
+Calculates the binomial coefficient n over k, also called the "choose"
+function. The result is equivalent to:
+
+       ( n )      n!
+       | - |  = -------
+       ( k )    k!(n-k)!
+
+This method was added in v1.84 of Math::BigInt (April 2007).
+
+=head2 bpi()
+
+       print Math::BigInt->bpi(100), "\n";             # 3
+
+Returns PI truncated to an integer, with the argument being ignored. that
+is it always returns C<3>.
+
+If upgrading is in effect, returns PI to N digits (including the "3"
+before the dot):
+
+       use Math::BigFloat;
+       use Math::BigInt upgrade => Math::BigFloat;
+       print Math::BigInt->bpi(3), "\n";               # 3.14
+       print Math::BigInt->bpi(100), "\n";             # 3.1415....
+
+This method was added in v1.87 of Math::BigInt (June 2007).
+
+=head2 bcos()
+
+       my $x = Math::BigFloat->new(1);
+       print $x->bcos(100), "\n";
+
+Calculate the cosinus of $x, modifying $x in place.
+
+This method was added in v1.87 of Math::BigInt (June 2007).
+
+=head2 bsin()
+
+       my $x = Math::BigFloat->new(1);
+       print $x->bsin(100), "\n";
+
+Calculate the sinus of $x, modifying $x in place.
+
+This method was added in v1.87 of Math::BigInt (June 2007).
+
+=head2 batan()
+
+       my $x = Math::BigFloat->new(0.5);
+       print $x->batan(100), "\n";
+
+Calculate the arcus tanges of $x, modifying $x in place.
+
+This method was added in v1.87 of Math::BigInt (June 2007).
+
 =head2 blsft()
 
-       $x->blsft($y);          # left shift
+       $x->blsft($y);          # left shift in base 2
        $x->blsft($y,$n);       # left shift, in base $n (like 10)
 
 =head2 brsft()
 
-       $x->brsft($y);          # right shift 
+       $x->brsft($y);          # right shift in base 2
        $x->brsft($y,$n);       # right shift, in base $n (like 10)
 
 =head2 band()
@@ -3717,7 +4087,7 @@ This is how it works now:
 
 =item Creating numbers
 
-  * When you create a number, you can give it's desired A or P via:
+  * When you create a number, you can give the desired A or P via:
     $x = Math::BigInt->new($number,$A,$P);
   * Only one of A or P can be defined, otherwise the result is NaN
   * If no A or P is give ($x = Math::BigInt->new($number) form), then the
@@ -3726,7 +4096,7 @@ This is how it works now:
     $x will be what was in effect when $x was created)
   * If given undef for A and P, B<no> rounding will occur, and the globals will
     B<not> be used. This is used by subclasses to create numbers without
-    suffering rounding in the parent. Thus a subclass is able to have it's own
+    suffering rounding in the parent. Thus a subclass is able to have its own
     globals enforced upon creation of a number by using
     C<< $x = Math::BigInt->new($number,undef,undef) >>:
 
@@ -4152,7 +4522,7 @@ needs to merely change the output only needs to overload C<bstr()>.
 All other object methods and overloaded functions can be directly inherited
 from the parent class.
 
-At the very minimum, any subclass will need to provide it's own C<new()> and can
+At the very minimum, any subclass will need to provide its own C<new()> and can
 store additional hash keys in the object. There are also some package globals
 that must be defined, e.g.:
 
@@ -4217,6 +4587,8 @@ is in effect, they will always hand up their work:
 
 =item blog()
 
+=item bexp()
+
 =back
 
 Beware: This list is not complete.
@@ -4225,6 +4597,13 @@ All other methods upgrade themselves only when one (or all) of their
 arguments are of the class mentioned in $upgrade (This might change in later
 versions to a more sophisticated scheme):
 
+=head1 EXPORTS
+
+C<Math::BigInt> exports nothing by default, but can export the following methods:
+
+       bgcd
+       blcm
+
 =head1 BUGS
 
 =over 2
@@ -4263,7 +4642,7 @@ Both C<bstr()> and C<bsstr()> as well as automated stringify via overload now
 drop the leading '+'. The old code would return '+3', the new returns '3'.
 This is to be consistent with Perl and to make C<cmp> (especially with
 overloading) to work as you expect. It also solves problems with C<Test.pm>,
-because it's C<ok()> uses 'eq' internally. 
+because its C<ok()> uses 'eq' internally. 
 
 Mark Biggar said, when asked about to drop the '+' altogether, or make only
 C<cmp> work: