International PHP Conference 2019 - Spring Edition

# BCMath Arbitrary Precision Mathematics

• Introduction
• Installing/Configuring
• Predefined Constants
• BC Math Functions
• bccomp — Compare two arbitrary precision numbers
• bcdiv — Divide two arbitrary precision numbers
• bcmod — Get modulus of an arbitrary precision number
• bcmul — Multiply two arbitrary precision numbers
• bcpow — Raise an arbitrary precision number to another
• bcpowmod — Raise an arbitrary precision number to another, reduced by a specified modulus
• bcscale — Set default scale parameter for all bc math functions
• bcsqrt — Get the square root of an arbitrary precision number
• bcsub — Subtract one arbitrary precision number from another

### User Contributed Notes 6 notes

15
Hayley Watson
2 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. ```
14
3 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;}?> ```
11
ClaudiuS
5 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?> ```
Anonymous
1 year 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)); ```
-3
George Lund
4 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. ```
-4
Artur Kuritsyn
1 year 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)); ```