From: Jarkko Hietaniemi Date: Mon, 4 Mar 2002 01:18:02 +0000 (+0000) Subject: Upgrade to Math::BigInt 1.54. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=9393ace2f22338dd25b6a689e53031fa2599038f;p=p5sagit%2Fp5-mst-13.2.git Upgrade to Math::BigInt 1.54. p4raw-id: //depot/perl@14972 --- diff --git a/lib/Math/BigFloat.pm b/lib/Math/BigFloat.pm index b7120cc..ad6588e 100644 --- a/lib/Math/BigFloat.pm +++ b/lib/Math/BigFloat.pm @@ -155,8 +155,7 @@ sub new } return $downgrade->new("$$mis$$miv$$mfv"."E$$es$$ev"); } - - # print "mbf new $self->{sign} $self->{_m} e $self->{_e}\n"; + # print "mbf new $self->{sign} $self->{_m} e $self->{_e} ",ref($self),"\n"; $self->bnorm()->round(@r); # first normalize, then round } @@ -192,6 +191,13 @@ sub _bzero $self->{_e} = Math::BigInt->bone(); } +sub isa + { + my ($self,$class) = @_; + return if $class eq 'Math::BigInt'; # we aren't + return UNIVERSAL::isa($self,$class); + } + ############################################################################## # string conversation @@ -559,12 +565,19 @@ sub blog # http://www.efunda.com/math/taylor_series/logarithmic.cfm?search_string=log - # u = x-1, v = x +1 + # u = x-1, v = x+1 # _ _ - # taylor: | u 1 u^3 1 u^5 | + # Taylor: | u 1 u^3 1 u^5 | # ln (x) = 2 | --- + - * --- + - * --- + ... | x > 0 # |_ v 3 v^3 5 v^5 _| + # This takes much more steps to calculate the result: + # u = x-1 + # _ _ + # Taylor: | u 1 u^2 1 u^3 | + # ln (x) = 2 | --- + - * --- + - * --- + ... | x > 1/2 + # |_ x 2 x^2 3 x^3 _| + # we need to limit the accuracy to protect against overflow my $fallback = 0; my $scale = 0; @@ -598,34 +611,56 @@ sub blog # we also need to disable any set A or P on $x (_find_round_parameters took # them already into account), since these would interfere, too delete $x->{_a}; delete $x->{_p}; - # need to disable $upgrade in BigInt, to aoid deep recursion + # need to disable $upgrade in BigInt, to avoid deep recursion local $Math::BigInt::upgrade = undef; - - my $v = $x->copy(); $v->binc(); # v = x+1 - $x->bdec(); my $u = $x->copy(); # u = x-1; x = x-1 - - $x->bdiv($v,$scale); # first term: u/v - - my $below = $v->copy(); - my $over = $u->copy(); - $u *= $u; $v *= $v; # u^2, v^2 - $below->bmul($v); # u^3, v^3 - $over->bmul($u); - my $factor = $self->new(3); my $two = $self->new(2); - - my $diff = $self->bone(); - my $limit = $self->new("1E-". ($scale-1)); my $last; - # print "diff $diff limit $limit\n"; - while ($diff->bcmp($limit) > 0) - { - #print "$x $over $below $factor\n"; - $diff = $x->copy()->bsub($last)->babs(); - #print "diff $diff $limit\n"; - $last = $x->copy(); - $x += $over->copy()->bdiv($below->copy()->bmul($factor),$scale); - $over *= $u; $below *= $v; $factor->badd($two); - } - $x->bmul($two); + + my ($case,$limit,$v,$u,$below,$factor,$two,$next,$over,$f); + + if (3 < 5) + #if ($x <= Math::BigFloat->new("0.5")) + { + $case = 0; + # print "case $case $x < 0.5\n"; + $v = $x->copy(); $v->binc(); # v = x+1 + $x->bdec(); $u = $x->copy(); # u = x-1; x = x-1 + $x->bdiv($v,$scale); # first term: u/v + $below = $v->copy(); + $over = $u->copy(); + $u *= $u; $v *= $v; # u^2, v^2 + $below->bmul($v); # u^3, v^3 + $over->bmul($u); + $factor = $self->new(3); $f = $self->new(2); + } + #else + # { + # $case = 1; + # print "case 1 $x > 0.5\n"; + # $v = $x->copy(); # v = x + # $u = $x->copy(); $u->bdec(); # u = x-1; + # $x->bdec(); $x->bdiv($v,$scale); # first term: x-1/x + # $below = $v->copy(); + # $over = $u->copy(); + # $below->bmul($v); # u^2, v^2 + # $over->bmul($u); + # $factor = $self->new(2); $f = $self->bone(); + # } + $limit = $self->new("1E-". ($scale-1)); + #my $steps = 0; + while (3 < 5) + { + # we calculate the next term, and add it to the last + # when the next term is below our limit, it won't affect the outcome + # anymore, so we stop + $next = $over->copy()->bdiv($below->copy()->bmul($factor),$scale); + last if $next->bcmp($limit) <= 0; + $x->badd($next); + # print "step $steps $x\n"; + # calculate things for the next term + $over *= $u; $below *= $v; $factor->badd($f); + #$steps++; + } + $x->bmul(2) if $case == 0; + #print "took $steps steps\n"; # shortcut to not run trough _find_round_parameters again if (defined $params[1]) @@ -758,7 +793,7 @@ sub bmul sub bdiv { # (dividend: BFLOAT or num_str, divisor: BFLOAT or num_str) return - # (BFLOAT,BFLOAT) (quo,rem) or BINT (only rem) + # (BFLOAT,BFLOAT) (quo,rem) or BFLOAT (only rem) my ($self,$x,$y,$a,$p,$r) = objectify(2,@_); return $self->_div_inf($x,$y) @@ -767,8 +802,8 @@ sub bdiv # x== 0 # also: or y == 1 or y == -1 return wantarray ? ($x,$self->bzero()) : $x if $x->is_zero(); - # upgrade - return $upgrade->bdiv($x,$y,$a,$p,$r) if defined $upgrade; + # upgrade ? + return $upgrade->bdiv($upgrade->new($x),$y,$a,$p,$r) if defined $upgrade; # we need to limit the accuracy to protect against overflow my $fallback = 0; @@ -811,6 +846,10 @@ sub bdiv # promote BigInts and it's subclasses (except when already a BigFloat) $y = $self->new($y) unless $y->isa('Math::BigFloat'); + #print "bdiv $y ",ref($y),"\n"; + # need to disable $upgrade in BigInt, to avoid deep recursion + local $Math::BigInt::upgrade = undef; # should be parent class vs MBI + # calculate the result to $scale digits and then round it # a * 10 ** b / c * 10 ** d => a/c * 10 ** (b-d) $x->{_m}->blsft($scale,10); @@ -852,7 +891,7 @@ sub bdiv } return ($x,$rem); } - return $x; + $x; } sub bmod @@ -965,19 +1004,20 @@ sub bsqrt } # when user set globals, they would interfere with our calculation, so - # disable then and later re-enable them + # disable them and later re-enable them no strict 'refs'; my $abr = "$self\::accuracy"; my $ab = $$abr; $$abr = undef; my $pbr = "$self\::precision"; my $pb = $$pbr; $$pbr = undef; # we also need to disable any set A or P on $x (_find_round_parameters took # them already into account), since these would interfere, too delete $x->{_a}; delete $x->{_p}; - # need to disable $upgrade in BigInt, to aoid deep recursion - local $Math::BigInt::upgrade = undef; + # need to disable $upgrade in BigInt, to avoid deep recursion + local $Math::BigInt::upgrade = undef; # should be really parent class vs MBI my $xas = $x->as_number(); my $gs = $xas->copy()->bsqrt(); # some guess +# print "guess $gs\n"; if (($x->{_e}->{sign} ne '-') # guess can't be accurate if there are # digits after the dot && ($xas->bacmp($gs * $gs) == 0)) # guess hit the nail on the head? @@ -998,6 +1038,7 @@ sub bsqrt # clear a/p after round, since user did not request it $x->{_a} = undef; $x->{_p} = undef; } + # re-enable A and P, upgrade is taken care of by "local" ${"$self\::accuracy"} = $ab; ${"$self\::precision"} = $pb; return $x; } @@ -1006,7 +1047,6 @@ sub bsqrt my $lx = $x->{_m}->length(); $scale = $lx if $scale < $lx; my $e = $self->new("1E-$scale"); # make test variable -# return $x->bnan() if $e->sign() eq 'NaN'; my $y = $x->copy(); my $two = $self->new(2); @@ -1015,10 +1055,11 @@ sub bsqrt $y = $self->new($y) unless $y->isa('Math::BigFloat'); my $rem; - while ($diff >= $e) + while ($diff->bacmp($e) >= 0) { + $rem = $y->copy()->bdiv($gs,$scale); $rem = $y->copy()->bdiv($gs,$scale)->badd($gs)->bdiv($two,$scale); - $diff = $rem->copy()->bsub($gs)->babs(); + $diff = $rem->copy()->bsub($gs); $gs = $rem->copy(); } # copy over to modify $x @@ -1063,6 +1104,98 @@ sub bfac $x->bnorm()->round(@r); } +sub _pow + { + # Calculate a power where $y is a non-integer, like 2 ** 0.5 + my ($x,$y,$a,$p,$r) = @_; + my $self = ref($x); + + # if $y == 0.5, it is sqrt($x) + return $x->bsqrt($a,$p,$r,$y) if $y->bcmp('0.5') == 0; + + # u = y * ln x + # _ _ + # Taylor: | u u^2 u^3 | + # x ** y = 1 + | --- + --- + * ----- + ... | + # |_ 1 1*2 1*2*3 _| + + # we need to limit the accuracy to protect against overflow + my $fallback = 0; + my $scale = 0; + my @params = $x->_find_round_parameters($a,$p,$r); + + # no rounding at all, so must use fallback + if (scalar @params == 1) + { + # simulate old behaviour + $params[1] = $self->div_scale(); # and round to it as accuracy + $scale = $params[1]+4; # at least four more for proper round + $params[3] = $r; # round mode by caller or undef + $fallback = 1; # to clear a/p afterwards + } + else + { + # the 4 below is empirical, and there might be cases where it is not + # enough... + $scale = abs($params[1] || $params[2]) + 4; # take whatever is defined + } + + # when user set globals, they would interfere with our calculation, so + # disable then and later re-enable them + no strict 'refs'; + my $abr = "$self\::accuracy"; my $ab = $$abr; $$abr = undef; + my $pbr = "$self\::precision"; my $pb = $$pbr; $$pbr = undef; + # we also need to disable any set A or P on $x (_find_round_parameters took + # them already into account), since these would interfere, too + delete $x->{_a}; delete $x->{_p}; + # need to disable $upgrade in BigInt, to avoid deep recursion + local $Math::BigInt::upgrade = undef; + + my ($limit,$v,$u,$below,$factor,$next,$over); + + $u = $x->copy()->blog($scale)->bmul($y); + $v = $self->bone(); # 1 + $factor = $self->new(2); # 2 + $x->bone(); # first term: 1 + + $below = $v->copy(); + $over = $u->copy(); + + $limit = $self->new("1E-". ($scale-1)); + #my $steps = 0; + while (3 < 5) + { + # we calculate the next term, and add it to the last + # when the next term is below our limit, it won't affect the outcome + # anymore, so we stop + $next = $over->copy()->bdiv($below,$scale); + last if $next->bcmp($limit) <= 0; + $x->badd($next); +# print "at $x\n"; + # calculate things for the next term + $over *= $u; $below *= $factor; $factor->binc(); + #$steps++; + } + + # shortcut to not run trough _find_round_parameters again + if (defined $params[1]) + { + $x->bround($params[1],$params[3]); # then round accordingly + } + else + { + $x->bfround($params[2],$params[3]); # then round accordingly + } + if ($fallback) + { + # clear a/p after round, since user did not request it + $x->{_a} = undef; $x->{_p} = undef; + } + # restore globals + $$abr = $ab; $$pbr = $pb; + $x; + } + sub bpow { # (BFLOAT or num_str, BFLOAT or num_str) return BFLOAT @@ -1075,7 +1208,10 @@ sub bpow return $x->bnan() if $x->{sign} eq $nan || $y->{sign} eq $nan; return $x->bone() if $y->is_zero(); return $x if $x->is_one() || $y->is_one(); - my $y1 = $y->as_number(); # make bigint (trunc) + + return $x->_pow($y,$a,$p,$r) if !$y->is_int(); # non-integer power + + my $y1 = $y->as_number(); # make bigint # if ($x == -1) if ($x->{sign} eq '-' && $x->{_m}->is_one() && $x->{_e}->is_zero()) { diff --git a/lib/Math/BigInt.pm b/lib/Math/BigInt.pm index f6279a8..abe2c82 100644 --- a/lib/Math/BigInt.pm +++ b/lib/Math/BigInt.pm @@ -18,7 +18,7 @@ package Math::BigInt; my $class = "Math::BigInt"; require 5.005; -$VERSION = '1.53'; +$VERSION = '1.54'; use Exporter; @ISA = qw( Exporter ); @EXPORT_OK = qw( objectify _swap bgcd blcm); @@ -164,7 +164,8 @@ sub upgrade # make Class->upgrade() work my $self = shift; my $class = ref($self) || $self || __PACKAGE__; - if (defined $_[0]) + # need to set new value? + if (@_ > 0) { my $u = shift; return ${"${class}::upgrade"} = $u; @@ -178,7 +179,8 @@ sub downgrade # make Class->downgrade() work my $self = shift; my $class = ref($self) || $self || __PACKAGE__; - if (defined $_[0]) + # need to set new value? + if (@_ > 0) { my $u = shift; return ${"${class}::downgrade"} = $u; @@ -396,11 +398,35 @@ sub new # avoid numify-calls by not using || on $wanted! return $class->bzero($a,$p) if !defined $wanted; # default to 0 - return $class->copy($wanted,$a,$p,$r) if ref($wanted); + return $class->copy($wanted,$a,$p,$r) + if ref($wanted) && $wanted->isa($class); # MBI or subclass $class->import() if $IMPORT == 0; # make require work - my $self = {}; bless $self, $class; + my $self = bless {}, $class; + + # shortcut for "normal" numbers + if ((!ref $wanted) && ($wanted =~ /^([+-]?)[1-9][0-9]*$/)) + { + $self->{sign} = $1 || '+'; + my $ref = \$wanted; + if ($wanted =~ /^[+-]/) + { + # remove sign without touching wanted + my $t = $wanted; $t =~ s/^[+-]//; $ref = \$t; + } + $self->{value} = $CALC->_new($ref); + no strict 'refs'; + if ( (defined $a) || (defined $p) + || (defined ${"${class}::precision"}) + || (defined ${"${class}::accuracy"}) + ) + { + $self->round($a,$p,$r) unless (@_ == 4 && !defined $a && !defined $p); + } + return $self; + } + # handle '+inf', '-inf' first if ($wanted =~ /^[+-]?inf$/) { @@ -473,8 +499,7 @@ sub new # do not round for new($x,undef,undef) since that is used by MBF to signal # no rounding $self->round($a,$p,$r) unless @_ == 4 && !defined $a && !defined $p; - # print "mbi new $self\n"; - return $self; + $self; } sub bnan @@ -649,7 +674,7 @@ sub numify return $x->{sign} if $x->{sign} !~ /^[+-]$/; my $num = $CALC->_num($x->{value}); return -$num if $x->{sign} eq '-'; - return $num; + $num; } ############################################################################## @@ -657,10 +682,10 @@ sub numify sub sign { - # return the sign of the number: +/-/NaN + # return the sign of the number: +/-/-inf/+inf/NaN my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_); - return $x->{sign}; + $x->{sign}; } sub _find_round_parameters @@ -1102,6 +1127,7 @@ sub is_inf my ($self,$x,$sign) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_); $sign = '' if !defined $sign; + return 1 if $sign eq $x->{sign}; # match ("+inf" eq "+inf") return 0 if $sign !~ /^([+-]|)$/; if ($sign eq '') @@ -1187,8 +1213,6 @@ sub bmul return $x if $x->modify('bmul'); - $r[3] = $y; # no push here - return $x->bnan() if (($x->{sign} eq $nan) || ($y->{sign} eq $nan)); # inf handling @@ -1202,6 +1226,11 @@ sub bmul return $x->binf() if ($x->{sign} =~ /^-/ && $y->{sign} =~ /^-/); return $x->binf('-'); } + + return $upgrade->bmul($x,$y,@r) + if defined $upgrade && $y->isa($upgrade); + + $r[3] = $y; # no push here $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-'; # +1 * +1 or -1 * -1 => + @@ -1266,6 +1295,9 @@ sub bdiv return $self->_div_inf($x,$y) if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/) || $y->is_zero()); + return $upgrade->bdiv($upgrade->new($x),$y,@r) + if defined $upgrade && $y->isa($upgrade); + $r[3] = $y; # no push! # 0 / something @@ -1276,7 +1308,8 @@ sub bdiv my $cmp = $CALC->_acmp($x->{value},$y->{value}); if (($cmp < 0) and (($x->{sign} eq $y->{sign}) or !wantarray)) { - return $upgrade->bdiv($x,$y,@r) if defined $upgrade; + return $upgrade->bdiv($upgrade->new($x),$upgrade->new($y),@r) + if defined $upgrade; return $x->bzero()->round(@r) unless wantarray; my $t = $x->copy(); # make copy first, because $x->bzero() clobbers $x @@ -1289,6 +1322,8 @@ sub bdiv return $x unless wantarray; return ($x->round(@r),$self->bzero(@r)); } + return $upgrade->bdiv($upgrade->new($x),$upgrade->new($y),@r) + if defined $upgrade; # calc new sign and in case $y == +/- 1, return $x my $xsign = $x->{sign}; # keep @@ -1399,7 +1434,10 @@ sub bpow my ($self,$x,$y,@r) = objectify(2,@_); return $x if $x->modify('bpow'); - + + return $upgrade->bpow($upgrade->new($x),$y,@r) + if defined $upgrade && $y->isa($upgrade); + $r[3] = $y; # no push! return $x if $x->{sign} =~ /^[+-]inf$/; # -inf/+inf ** x return $x->bnan() if $x->{sign} eq $nan || $y->{sign} eq $nan; @@ -2038,13 +2076,10 @@ sub objectify # $x->unary_op(); return (ref($_[1]),$_[1]) if (@_ == 2) && ($_[0]||0 == 1) && ref($_[1]); - # $x->binary_op($y); - #return (ref($_[1]),$_[1],$_[2]) if (@_ == 3) && ($_[0]||0 == 2) - # && ref($_[1]) && ref($_[2]); my $count = abs(shift || 0); - my @a; # resulting array + my (@a,$k,$d); # resulting array, temp, and downgrade if (ref $_[0]) { # okay, got object as first @@ -2056,8 +2091,15 @@ sub objectify $a[0] = $class; $a[0] = shift if $_[0] =~ /^[A-Z].*::/; # classname as first? } + no strict 'refs'; + # disable downgrading, because Math::BigFLoat->foo('1.0','2.0') needs floats + if (defined ${"$a[0]::downgrade"}) + { + $d = ${"$a[0]::downgrade"}; + ${"$a[0]::downgrade"} = undef; + } + # print "Now in objectify, my class is today $a[0]\n"; - my $k; if ($count == 0) { while (@_) @@ -2095,6 +2137,7 @@ sub objectify push @a,@_; # return other params, too } die "$class objectify needs list context" unless wantarray; + ${"$a[0]::downgrade"} = $d; @a; } diff --git a/lib/Math/BigInt/Calc.pm b/lib/Math/BigInt/Calc.pm index fae8cae..de4f46e 100644 --- a/lib/Math/BigInt/Calc.pm +++ b/lib/Math/BigInt/Calc.pm @@ -8,7 +8,7 @@ require Exporter; use vars qw/@ISA $VERSION/; @ISA = qw(Exporter); -$VERSION = '0.24'; +$VERSION = '0.25'; # Package to store unsigned big integers in decimal and do math with them @@ -234,8 +234,8 @@ sub _to_small sub _new { # (ref to string) return ref to num_array - # Convert a number from string format to internal base 100000 format. - # Assumes normalized value as input. + # Convert a number from string format (without sign) to internal base + # 1ex format. Assumes normalized value as input. my $d = $_[1]; my $il = length($$d)-1; # this leaves '00000' instead of int 0 and will be corrected after any op @@ -390,7 +390,7 @@ sub _dec sub _sub { - # (ref to int_num_array, ref to int_num_array) + # (ref to int_num_array, ref to int_num_array, swap) # subtract base 1eX numbers -- stolen from Knuth Vol 2 pg 232, $x > $y # subtract Y from X (X is always greater/equal!) by modifying x in place my ($c,$sx,$sy,$s) = @_; @@ -419,9 +419,46 @@ sub _sub __strip_zeros($sy); } +sub _square_use_mul + { + # compute $x ** 2 or $x * $x in-place and return $x + my ($c,$x) = @_; + + # From: Handbook of Applied Cryptography by A. Menezes, P. van Oorschot and + # S. Vanstone., Chapter 14 + + #14.16 Algorithm Multiple-precision squaring + #INPUT: positive integer x = (xt 1 xt 2 ... x1 x0)b. + #OUTPUT: x * x = x ** 2 in radix b representation. + #1. For i from 0 to (2t - 1) do: wi <- 0. + #2. For i from 0 to (t - 1) do the following: + # 2.1 (uv)b w2i + xi * xi, w2i v, c u. + # 2.2 For j from (i + 1)to (t - 1) do the following: + # (uv)b <- wi+j + 2*xj * xi + c, wi+j <- v, c <- u. + # 2.3 wi+t <- u. + #3. Return((w2t-1 w2t-2 ... w1 w0)b). + +# # Note: That description is crap. Half of the symbols are not explained or +# # used with out beeing set. +# my $t = scalar @$x; # count +# my ($c,$i,$j); +# for ($i = 0; $i < $t; $i++) +# { +# $x->[$i] = $x->[$i*2] + $x[$i]*$x[$i]; +# $x->[$i*2] = $x[$i]; $c = $x[$i]; +# for ($j = $i+1; $j < $t; $j++) +# { +# $x->[$i] = $x->[$i+$j] + 2 * $x->[$i] * $x->[$j]; +# $x->[$i+$j] = $x[$j]; $c = $x[$i]; +# } +# $x->[$i+$t] = $x[$i]; +# } + $x; + } + sub _mul_use_mul { - # (BINT, BINT) return nothing + # (ref to int_num_array, ref to int_num_array) # multiply two numbers in internal representation # modifies first arg, second need not be different from first my ($c,$xv,$yv) = @_; @@ -446,6 +483,9 @@ sub _mul_use_mul # since multiplying $x with $x fails, make copy in this case $yv = [@$xv] if "$xv" eq "$yv"; # same references? + # since multiplying $x with $x would fail here, use the faster squaring +# return _square($c,$xv) if "$xv" eq "$yv"; # same reference? + if ($LEN_CONVERT != 0) { $c->_to_small($xv); $c->_to_small($yv); @@ -496,7 +536,7 @@ sub _mul_use_mul sub _mul_use_div { - # (BINT, BINT) return nothing + # (ref to int_num_array, ref to int_num_array) # multiply two numbers in internal representation # modifies first arg, second need not be different from first my ($c,$xv,$yv) = @_; @@ -523,6 +563,9 @@ sub _mul_use_div # since multiplying $x with $x fails, make copy in this case $yv = [@$xv] if "$xv" eq "$yv"; # same references? + # since multiplying $x with $x would fail here, use the faster squaring +# return _square($c,$xv) if "$xv" eq "$yv"; # same reference? + if ($LEN_CONVERT != 0) { $c->_to_small($xv); $c->_to_small($yv); @@ -865,9 +908,14 @@ sub _acmp # manual way (abort if unequal, good for early ne) my $j = scalar @$cx - 1; while ($j >= 0) - { - last if ($a = $cx->[$j] - $cy->[$j]); $j--; - } + { + last if ($a = $cx->[$j] - $cy->[$j]); $j--; + } +# my $j = scalar @$cx; +# while (--$j >= 0) +# { +# last if ($a = $cx->[$j] - $cy->[$j]); +# } return 1 if $a > 0; return -1 if $a < 0; 0; # equal diff --git a/lib/Math/BigInt/t/bare_mbf.t b/lib/Math/BigInt/t/bare_mbf.t index 78668c3..8288d2b 100644 --- a/lib/Math/BigInt/t/bare_mbf.t +++ b/lib/Math/BigInt/t/bare_mbf.t @@ -26,7 +26,7 @@ BEGIN } print "# INC = @INC\n"; - plan tests => 1586; + plan tests => 1592; } use Math::BigInt lib => 'BareCalc'; diff --git a/lib/Math/BigInt/t/bare_mbi.t b/lib/Math/BigInt/t/bare_mbi.t index 3d8d086..d480062 100644 --- a/lib/Math/BigInt/t/bare_mbi.t +++ b/lib/Math/BigInt/t/bare_mbi.t @@ -26,7 +26,7 @@ BEGIN } print "# INC = @INC\n"; - plan tests => 2143; + plan tests => 2147; } use Math::BigInt lib => 'BareCalc'; @@ -37,7 +37,7 @@ use vars qw ($class $try $x $y $f @args $ans $ans1 $ans1_str $setup $CL); $class = "Math::BigInt"; $CL = "Math::BigInt::BareCalc"; -my $version = '1.51'; # for $VERSION tests, match current release (by hand!) +my $version = '1.54'; # for $VERSION tests, match current release (by hand!) require 'bigintpm.inc'; # perform same tests as bigintpm diff --git a/lib/Math/BigInt/t/bigfltpm.t b/lib/Math/BigInt/t/bigfltpm.t index 28ae2b3..2b4f83a 100755 --- a/lib/Math/BigInt/t/bigfltpm.t +++ b/lib/Math/BigInt/t/bigfltpm.t @@ -26,7 +26,7 @@ BEGIN } print "# INC = @INC\n"; - plan tests => 1586; + plan tests => 1592; } use Math::BigInt; diff --git a/lib/Math/BigInt/t/bigintpm.t b/lib/Math/BigInt/t/bigintpm.t index c62b943..eca2d29 100755 --- a/lib/Math/BigInt/t/bigintpm.t +++ b/lib/Math/BigInt/t/bigintpm.t @@ -10,7 +10,7 @@ BEGIN my $location = $0; $location =~ s/bigintpm.t//; unshift @INC, $location; # to locate the testing files chdir 't' if -d 't'; - plan tests => 2143; + plan tests => 2147; } use Math::BigInt; diff --git a/lib/Math/BigInt/t/config.t b/lib/Math/BigInt/t/config.t index c3a222b..fc3e52f 100644 --- a/lib/Math/BigInt/t/config.t +++ b/lib/Math/BigInt/t/config.t @@ -22,7 +22,7 @@ my $cfg = Math::BigInt->config(); ok (ref($cfg),'HASH'); ok ($cfg->{lib},'Math::BigInt::Calc'); -ok ($cfg->{lib_version},'0.24'); +ok ($cfg->{lib_version},'0.25'); ok ($cfg->{class},'Math::BigInt'); ok ($cfg->{upgrade}||'',''); ok ($cfg->{div_scale},40); diff --git a/lib/Math/BigInt/t/downgrade.t b/lib/Math/BigInt/t/downgrade.t index 1309894..0208a56 100644 --- a/lib/Math/BigInt/t/downgrade.t +++ b/lib/Math/BigInt/t/downgrade.t @@ -7,13 +7,13 @@ BEGIN { $| = 1; unshift @INC, '../lib'; # for running manually - my $location = $0; $location =~ s/bigintpm.t//; + my $location = $0; $location =~ s/downgrade.t//; unshift @INC, $location; # to locate the testing files chdir 't' if -d 't'; - plan tests => 10; + plan tests => 12; } -use Math::BigInt; +use Math::BigInt upgrade => 'Math::BigFloat'; use Math::BigFloat downgrade => 'Math::BigInt', upgrade => 'Math::BigInt'; use vars qw ($scale $class $try $x $y $f @args $ans $ans1 $ans1_str $setup @@ -36,4 +36,14 @@ ok (ref(Math::BigFloat->new('10')),'Math::BigInt'); ok (ref(Math::BigFloat->new('-10')),'Math::BigInt'); ok (ref(Math::BigFloat->new('-10.0E1')),'Math::BigInt'); +# disable, otherwise it screws calculations +Math::BigFloat->upgrade(undef); +ok (Math::BigFloat->upgrade()||'',''); + +Math::BigFloat->div_scale(20); # make it a bit faster +my $x = Math::BigFloat->new(2); # downgrades +# the following test upgrade for bsqrt() and also makes new() NOT downgrade +# for the bpow() side +ok (Math::BigFloat->bpow('2','0.5'),$x->bsqrt()); + #require 'upgrade.inc'; # all tests here for sharing diff --git a/lib/Math/BigInt/t/sub_mbf.t b/lib/Math/BigInt/t/sub_mbf.t index 2035035..3df9ce4 100755 --- a/lib/Math/BigInt/t/sub_mbf.t +++ b/lib/Math/BigInt/t/sub_mbf.t @@ -26,8 +26,8 @@ BEGIN } print "# INC = @INC\n"; - plan tests => 1586 - + 4; # + 4 own tests + plan tests => 1592 + + 6; # + our own tests } use Math::BigFloat::Subclass; @@ -38,10 +38,15 @@ $CL = "Math::BigInt::Calc"; require 'bigfltpm.inc'; # perform same tests as bigfltpm +############################################################################### # Now do custom tests for Subclass itself my $ms = $class->new(23); print "# Missing custom attribute \$ms->{_custom}" if !ok (1, $ms->{_custom}); +# Check that subclass is a Math::BigFloat, but not a Math::Bigint +ok ($ms->isa('Math::BigFloat'),1); +ok ($ms->isa('Math::BigInt') || 0,0); + use Math::BigFloat; my $bf = Math::BigFloat->new(23); # same as other diff --git a/lib/Math/BigInt/t/sub_mbi.t b/lib/Math/BigInt/t/sub_mbi.t index d0a235a..c492592 100755 --- a/lib/Math/BigInt/t/sub_mbi.t +++ b/lib/Math/BigInt/t/sub_mbi.t @@ -26,8 +26,8 @@ BEGIN } print "# INC = @INC\n"; - plan tests => 2143 - + 4; # +4 own tests + plan tests => 2147 + + 5; # +4 own tests } use Math::BigInt::Subclass; @@ -40,10 +40,15 @@ my $version = '0.02'; # for $VERSION tests, match current release (by hand!) require 'bigintpm.inc'; # perform same tests as bigintpm +############################################################################### # Now do custom tests for Subclass itself + my $ms = $class->new(23); print "# Missing custom attribute \$ms->{_custom}" if !ok (1, $ms->{_custom}); +# Check that a subclass is still considered a BigInt +ok ($ms->isa('Math::BigInt'),1); + use Math::BigInt; my $bi = Math::BigInt->new(23); # same as other diff --git a/lib/Math/BigInt/t/upgrade.t b/lib/Math/BigInt/t/upgrade.t index 86bd139..17d505c 100644 --- a/lib/Math/BigInt/t/upgrade.t +++ b/lib/Math/BigInt/t/upgrade.t @@ -6,27 +6,12 @@ use strict; BEGIN { $| = 1; - # to locate the testing files - my $location = $0; $location =~ s/upgrade.t//i; - if ($ENV{PERL_CORE}) - { - @INC = qw(../t/lib); # testing with the core distribution - } - unshift @INC, '../lib'; # for testing manually - if (-d 't') - { - chdir 't'; - require File::Spec; - unshift @INC, File::Spec->catdir(File::Spec->updir, $location); - } - else - { - unshift @INC, $location; - } - print "# INC = @INC\n"; - - plan tests => 1990 - + 2; # our own tests + unshift @INC, '../lib'; # for running manually + my $location = $0; $location =~ s/bigintpm.t//; + unshift @INC, $location; # to locate the testing files + chdir 't' if -d 't'; + plan tests => 2056 + + 2; # our own tests } use Math::BigInt upgrade => 'Math::BigFloat';