Search code examples
phpmathbcmath

PHP: How to raise number to (tiny) fractional exponent?


I'm doing a calculation in PHP using bcmath, and need to raise e by a fractional exponent. Unfortunately, bcpow() only accepts integer exponents. The exponent is typically higher precision than a float will allow, so normal arithmetic functions won't cut it.

For example:

$e = exp(1);
$pow = "0.000000000000000000108420217248550443400745280086994171142578125";
$result = bcpow($e, $pow);

Result is "1" with the error, "bc math warning: non-zero scale in exponent".

Is there another function I can use instead of bcpow()?


Solution

  • Your best bet is probably to use the Taylor series expansion. As you noted, PHP's bcpow is limited to raising to integer exponentiation.

    So what you can do is roll your own bc factorial function and use the wiki page to implement a Taylor series expansion of the exponential function.

    function bcfac($num) { 
        if ($num==0) return 1;
        $result = '1';
        for ( ; $num > 0; $num--)
            $result = bcmul($result,$num);
        return $result;
    }
    $mysum = '0';
    for ($i=0; $i<300; $i++) {
        $mysum = bcadd($mysum, bcdiv(bcpow($pow,$i), bcfac($i)) );
    }
    print $mysum;
    

    Obviously, the $i<300 is an approximation for infinity... You can change it to suit your performance needs.

    With $i=20, I got

    1.00000000000000000010842021724855044340662275184110560868263421994092888869270293594926619547803962155136242752708629105688492780863293090291376157887898519458498571566021915144483905034693109606778068801680332504212458366799913406541920812216634834265692913062346724688397654924947370526356787052264726969653983148004800229537555582281617497990286595977830803702329470381960270717424849203303593850108090101578510305396615293917807977774686848422213799049363135722460179809890014584148659937665374616

    This is comforting since that small of an exponent should yield something really close to 1.0.