CryptX
view release on metacpan or search on metacpan
lib/Math/BigInt/LTM.pm view on Meta::CPAN
return $sum;
}
### same as _num() in Math::BigInt::Lib
sub _num {
my ($class, $x) = @_;
0 + $class -> _str($x);
}
### PATCHED/OLDER _fac() from Math::BigInt::Lib
sub _fac {
# factorial
my ($class, $x) = @_;
my $two = $class -> _two();
if ($class -> _acmp($x, $two) < 0) {
###HACK: needed for MBI 1.999715 compatibility
###return $class -> _one();
$class->_set($x, 1); return $x
}
my $i = $class -> _copy($x);
while ($class -> _acmp($i, $two) > 0) {
$i = $class -> _dec($i);
$x = $class -> _mul($x, $i);
}
return $x;
}
### PATCHED _dfac() from Math::BigInt::Lib
sub _dfac {
# double factorial
my ($class, $x) = @_;
my $two = $class -> _two();
if ($class -> _acmp($x, $two) < 0) {
###HACK: needed for MBI 1.999715 compatibility
###return $class -> _one();
$class->_set($x, 1); return $x
}
my $i = $class -> _copy($x);
while ($class -> _acmp($i, $two) > 0) {
$i = $class -> _sub($i, $two);
$x = $class -> _mul($x, $i);
}
return $x;
}
### same as _nok() in Math::BigInt::Lib
sub _nok {
# Return binomial coefficient (n over k).
my ($class, $n, $k) = @_;
# If k > n/2, or, equivalently, 2*k > n, compute nok(n, k) as
# nok(n, n-k), to minimize the number if iterations in the loop.
{
my $twok = $class -> _mul($class -> _two(), $class -> _copy($k));
if ($class -> _acmp($twok, $n) > 0) {
$k = $class -> _sub($class -> _copy($n), $k);
}
}
# Example:
#
# / 7 \ 7! 1*2*3*4 * 5*6*7 5 * 6 * 7
# | | = --------- = --------------- = --------- = ((5 * 6) / 2 * 7) / 3
# \ 3 / (7-3)! 3! 1*2*3*4 * 1*2*3 1 * 2 * 3
#
# Equivalently, _nok(11, 5) is computed as
#
# (((((((7 * 8) / 2) * 9) / 3) * 10) / 4) * 11) / 5
if ($class -> _is_zero($k)) {
return $class -> _one();
}
# Make a copy of the original n, in case the subclass modifies n in-place.
my $n_orig = $class -> _copy($n);
# n = 5, f = 6, d = 2 (cf. example above)
$n = $class -> _sub($n, $k);
$n = $class -> _inc($n);
my $f = $class -> _copy($n);
$f = $class -> _inc($f);
my $d = $class -> _two();
# while f <= n (the original n, that is) ...
while ($class -> _acmp($f, $n_orig) <= 0) {
$n = $class -> _mul($n, $f);
$n = $class -> _div($n, $d);
$f = $class -> _inc($f);
$d = $class -> _inc($d);
}
return $n;
}
### same as _sadd() in Math::BigInt::Lib
# Signed addition. If the flag is false, $xa might be modified, but not $ya. If
# the false is true, $ya might be modified, but not $xa.
sub _sadd {
my $class = shift;
my ($xa, $xs, $ya, $ys, $flag) = @_;
my ($za, $zs);
# If the signs are equal we can add them (-5 + -3 => -(5 + 3) => -8)
if ($xs eq $ys) {
if ($flag) {
( run in 1.158 second using v1.01-cache-2.11-cpan-71847e10f99 )