Математические операции модуля BCMath с числами произвольной точности

  • Введение
  • Установка и настройка
  • Функции BC Math
    • bcadd — Сложить 2 числа произвольной точности
    • bccomp — Сравнение двух чисел произвольной точности
    • bcdiv — Операция деления для чисел произвольной точности
    • bcmod — Получает остаток от деления чисел с произвольной точностью
    • bcmul — Умножение двух чисел с произвольной точностью
    • bcpow — Возведение в степень чисел с произвольной точностью
    • bcpowmod — Возводит одно число в степень другого и возвращает остаток от деления результата на третье число
    • bcscale — Устанавливает или получает количество чисел после десятичной точки по умолчанию для всех функций bc math.
    • bcsqrt — Извлекает квадратный корень из числа с заданной точностью
    • bcsub — Вычитает одно число из другого с заданной точностью
add a note

User Contributed Notes 6 notes

up
75
Hayley Watson
8 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
24
volek at adamv dot cz
9 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
18
ClaudiuS
11 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
?>
up
-11
Artur Kuritsyn
6 years ago
Useful function for bcround

function getBcRound($number, $precision = 0)
{
$precision = ($precision < 0)
? 0
: (int) $precision;
if (strcmp(bcadd($number, '0', $precision), bcadd($number, '0', $precision+1)) == 0) {
return bcadd($number, '0', $precision);
}
if (getBcPresion($number) - $precision > 1) {
$number = getBcRound($number, $precision + 1);
}
$t = '0.' . str_repeat('0', $precision) . '5';
return $number < 0
? bcsub($number, $t, $precision)
: bcadd($number, $t, $precision);
}

function getBcPresion($number) {
$dotPosition = strpos($number, '.');
if ($dotPosition === false) {
return 0;
}
return strlen($number) - strpos($number, '.') - 1;
}

var_dump(getBcRound('3', 0) == number_format('3', 0));
var_dump(getBcRound('3.4', 0) == number_format('3.4', 0));
var_dump(getBcRound('3.56', 0) == number_format('3.6', 0));
var_dump(getBcRound('1.95583', 2) == number_format('1.95583', 2));
var_dump(getBcRound('5.045', 2) == number_format('5.045', 2));
var_dump(getBcRound('5.055', 2) == number_format('5.055', 2));
var_dump(getBcRound('9.999', 2) == number_format('9.999', 2));
var_dump(getBcRound('5.0445', 5) == number_format('5.044500', 5));
var_dump(getBcRound('5.0445', 4) == number_format('5.04450', 4));
var_dump(getBcRound('5.0445', 3) == number_format('5.0445', 3));
var_dump(getBcRound('5.0445', 2) == number_format('5.045', 2));
var_dump(getBcRound('5.0445', 1) == number_format('5.05', 1));
var_dump(getBcRound('5.0445', 0) == number_format('5.0', 0));//
var_dump(getBcRound('5.04455', 2) == number_format('5.045', 2));
var_dump(getBcRound('99.999', 2) == number_format('100.000', 2));
var_dump(getBcRound('99.999') == number_format('99.999', 0));
var_dump(getBcRound('99.999', 'a') == number_format('99.999', 0));
var_dump(getBcRound('99.999', -1.5) == number_format('99.999', 0));
var_dump(getBcRound('-0.00001', 2) == number_format('-0.000', 2));
var_dump(getBcRound('-0.0000', 2) == number_format('0', 2));
var_dump(getBcRound('-4.44455', 2) == number_format('-4.445', 2));
var_dump(getBcRound('-4.44555', 0) == number_format('-4.5', 0));
var_dump(getBcRound('-4.444444444444444444444444444444444444444444445', 0) == number_format('-4.5', 0));
up
-24
George Lund
10 years ago
It's worth noting that this library is named very wrongly.

It may be called 'Binary Calculator', but what you're getting is a decimal calculator that can represent base-10 fractions accurately.
up
-19
Anonymous
6 years ago
Useful function for bcround

function getBcRound($number, $precision = 0)
{
$precision = ($precision < 0)
? 0
: (int) $precision;
if (strcmp(bcadd($number, '0', $precision), bcadd($number, '0', $precision+1)) == 0) {
return bcadd($number, '0', $precision);
}
if (getBcPresion($number) - $precision > 1) {
$number = getBcRound($number, $precision + 1);
}
$t = '0.' . str_repeat('0', $precision) . '5';
return $number < 0
? bcsub($number, $t, $precision)
: bcadd($number, $t, $precision);
}

function getBcPresion($number) {
$dotPosition = strpos($number, '.');
if ($dotPosition === false) {
return 0;
}
return strlen($number) - strpos($number, '.') - 1;
}

var_dump(getBcRound('3', 0) == number_format('3', 0));
var_dump(getBcRound('3.4', 0) == number_format('3.4', 0));
var_dump(getBcRound('3.56', 0) == number_format('3.6', 0));
var_dump(getBcRound('1.95583', 2) == number_format('1.95583', 2));
var_dump(getBcRound('5.045', 2) == number_format('5.045', 2));
var_dump(getBcRound('5.055', 2) == number_format('5.055', 2));
var_dump(getBcRound('9.999', 2) == number_format('9.999', 2));
var_dump(getBcRound('5.0445', 5) == number_format('5.044500', 5));
var_dump(getBcRound('5.0445', 4) == number_format('5.04450', 4));
var_dump(getBcRound('5.0445', 3) == number_format('5.0445', 3));
var_dump(getBcRound('5.0445', 2) == number_format('5.045', 2));
var_dump(getBcRound('5.0445', 1) == number_format('5.05', 1));
var_dump(getBcRound('5.0445', 0) == number_format('5.0', 0));//
var_dump(getBcRound('5.04455', 2) == number_format('5.045', 2));
var_dump(getBcRound('99.999', 2) == number_format('100.000', 2));
var_dump(getBcRound('99.999') == number_format('99.999', 0));
var_dump(getBcRound('99.999', 'a') == number_format('99.999', 0));
var_dump(getBcRound('99.999', -1.5) == number_format('99.999', 0));
var_dump(getBcRound('-0.00001', 2) == number_format('-0.000', 2));
var_dump(getBcRound('-0.0000', 2) == number_format('0', 2));
var_dump(getBcRound('-4.44455', 2) == number_format('-4.445', 2));
var_dump(getBcRound('-4.44555', 0) == number_format('-4.5', 0));
var_dump(getBcRound('-4.444444444444444444444444444444444444444444445', 0) == number_format('-4.5', 0));
To Top