public function pow(Decimal $b, $scale = null)
{
if ($this->isZero()) {
if ($b->isPositive()) {
return Decimal::fromDecimal($this, $scale);
} else {
throw new \DomainException("zero can't be powered to zero or negative numbers.");
}
} elseif ($b->isZero()) {
return DecimalConstants::One();
} else {
if ($b->isNegative()) {
return DecimalConstants::One()->div($this->pow($b->additiveInverse()), $scale);
} elseif ($b->scale == 0) {
$pow_scale = $scale === null ? max($this->scale, $b->scale) : max($this->scale, $b->scale, $scale);
return self::fromString(bcpow($this->value, $b->value, $pow_scale + 1), $pow_scale);
} else {
if ($this->isPositive()) {
$pow_scale = $scale === null ? max($this->scale, $b->scale) : max($this->scale, $b->scale, $scale);
$truncated_b = bcadd($b->value, '0', 0);
$remaining_b = bcsub($b->value, $truncated_b, $b->scale);
$first_pow_approx = bcpow($this->value, $truncated_b, $pow_scale + 1);
$intermediate_root = self::innerPowWithLittleExponent($this->value, $remaining_b, $b->scale, $pow_scale + 1);
return Decimal::fromString(bcmul($first_pow_approx, $intermediate_root, $pow_scale + 1), $pow_scale);
} else {
// elseif ($this->isNegative())
if ($b->isInteger()) {
if (preg_match('/^[+\\-]?[0-9]*[02468](\\.0+)?$/', $b->value, $captures) === 1) {
// $b is an even number
return $this->additiveInverse()->pow($b, $scale);
} else {
// $b is an odd number
return $this->additiveInverse()->pow($b, $scale)->additiveInverse();
}
}
throw new NotImplementedException("Usually negative numbers can't be powered to non integer numbers. " . "The cases where is possible are not implemented.");
}
}
}
}