BCMath — розрахунки з довільною математичною точністю

Вступ

Для математичних обчислень з довільною точністю PHP пропонує розширення BC Math, яке дозволяє оперувати числами будь-якого розміру і точності, представленими у вигляді рядків, аж до 2147483647 (0x7FFFFFFF) знаків або обмежуючись виділеною пам'яттю.

Правильними числами для BCMath є рядки, що відповідають регулярному виразу /^[+-]?[0-9]*(\.[0-9]*)?$/.

Застереження

Передавання числа типу float в функції BCMath, які очікують операнди типу string, може не мати бажаного ефекту через спосіб, яким PHP перетворює float-значення в string, а саме: рядок (string) може отримати експонентний запис числа (що не підтримується BCMath); до PHP 8.0.0 символ десяткового розділювача залежить від локалі (тоді як BCMath очікує крапку).

<?php
$num1 = 0; // (string) 0 => '0'
$num2 = -0.000005; // (string) -0.000005 => '-5.05E-6'
echo bcadd($num1, $num2, 6); // => '0.000000'

setlocale(LC_NUMERIC, 'de_DE'); // розділювач — кома
$num2 = 1.2; // (string) 1.2 => '1,2'
echo bcsub($num1, $num2, 1); // => '0.0'
?>
add a note

User Contributed Notes 3 notes

up
75
Hayley Watson
10 years ago
This extension is an interface to the GNU implementation as a library of the Basic Calculator utility by Philip Nelson; hence the name.
up
22
volek at adamv dot cz
11 years ago
Note that when you use implementation of factorial that ClaudiuS made, you get results even if you try to calculate factorial of number that you normally can't, e.g. 2.5, -2, etc. Here is safer implementation:
<?php
/**
 * Calculates a factorial of given number.
 * @param string|int $num
 * @throws InvalidArgumentException
 * @return string
 */
function bcfact($num)
{
    if (!filter_var($num, FILTER_VALIDATE_INT) || $num <= 0) {
        throw new InvalidArgumentException(sprintf('Argument must be natural number, "%s" given.', $num));
    }

    for ($result = '1'; $num > 0; $num--) {
        $result = bcmul($result, $num);
    }

    return $result;
}
?>
up
20
ClaudiuS
13 years ago
Needed to compute some permutations and found the BC extension great but poor on functions, so untill this gets implemented here's the factorial function:

<?php
/* BC FACTORIAL
 * n! = n * (n-1) * (n-2) .. 1 [eg. 5! = 5 * 4 * 3 * 2 * 1 = 120]
 */
function bcfact($n){
    $factorial=$n;
    while (--$n>1) $factorial=bcmul($factorial,$n);
    return $factorial;
}

print bcfact(50); 
//30414093201713378043612608166064768844377641568960512000000000000
?>
To Top