PHP BCMath - BC高精准度函数库

BCBinary Calculator 的缩写。bc* 函数的参数都是操作数加上一个可选的 [int scale] ,比如

1
string bcadd(string $left_operand, string $right_operand[, int $scale])

如果 scale 没有提供,就用 bcscale 的缺省值。这里大数直接用一个由 0-9 组成的string表示,计算结果返回的也是一个 string。 默认 scale值在 php.ini 中配置:

1
2
3
4
[bcmath]
; Number of decimal digits for all bcmath functions.
; http://php.net/bcmath.scale
bcmath.scale = 0

一、开启 BCMATH 支持

  1. 编译时指定:--enable-bcmath
  2. 如果编译时没有开启,只能使用 phpize 等当做扩展重新安装,并在 php.ini 中添加 extension=bcmath.so 开启

二、函数列表

1、bcadd — 将两个高精度数字相加
1
string bcadd ( string $left_operand , string $right_operand [, int $scale ] )

左操作数和右操作数求和,$scale 设置结果中小数点后的小数位数。

1
2
3
4
5
6
7
8
9
10
11
# demo 1
echo bcadd("1", "2"); // 3
echo "1" + "2"; // 3
echo bcadd("1", "2 "); // 1
echo "1" + "2 "; // 3
echo bcadd("1", " 2"); // 1
echo "1" + " 2"; // 3

# demo 2
echo bcadd("1.33", "2.0"); // 3
echo bcadd(1, 3, 2); // 4.00

由上述 对比 demo1,bcadd 的运算参数只接受数字和浮点类型参数,不结束含有非数字类的字符串。这类参数会直接强制类型转换变成0,不同于 直接预算,会先进性 trim 操作后进行运算。

2、bccomp — 比较两个高精度数字,返回-1, 0, 1
1
int bccomp ( string $left_operand , string $right_operand [, int $scale = int ] )

如果两个数相等返回0, 左边的数left_operand比较右边的数right_operand大返回1, 否则返回-1.

可选的scale参数被用作设置指示数字, 代表参与比较的小数点后面的位数。

1
2
3
4
# demo
echo bccomp('1', '2'); // -1
echo bccomp('1.00001', '1', 3); // 0 - 三位小数参与比较,1.000 == 1
echo bccomp('1.00001', '1', 5); // 1 - 五位小数参与比较,1.00001 > 1
3、bcdiv — 将两个高精度数字相除
1
string bcdiv ( string $left_operand , string $right_operand [, int $scale = int ] )

左操作数除以右操作数。scale 此可选参数用于设置结果中小数点后的小数位数。返回结果为字符串类型的结果,如果右操作数是 0 结果为 null

4、bcmod — 求高精度数字余数
1
string bcmod ( string $left_operand , string $modulus )

对左操作数使用系数取模。

1
2
3
echo bcmod("5", "2"); // 1
echo bcmod("19", "7"); // 5
echo bcmod("15", "5"); // 0

注:经验证,bcmod 方法,也支持第三个参数 scale,但是结果有点奇怪,如下:

PS取模操作本身就是针对小数的,一下尝试纯属娱乐。

1
2
3
4
5
6
echo bcmod(7.33, 3);		// 1
echo bcmod(7.33, 3, 2); // 1.33
echo bcmod(1.33, 2, 3); // 1.33
echo bcmod(1.33, 1.22, 3); // 0.110
echo bcmod(1.33, 0.28, 3); // 0.210 →_→ 这个结果怎么出来的,有点奇怪
echo bcmod(1.33, 0.28); // 0 →_→ 也是一个奇怪的结果

由上可知,bcmod 方法的 scale 参数可以使用,但是如果右操作数小于0,则结果将失去意义。

5、bcmul — 将两个高精度数字相乘
1
string bcmul ( string $left_operand , string $right_operand [, int $scale = 0 ] )

左操作数乘以右操作数, scale 用于设置结果中小数点后的小数位数。

6、bcpow — 求高精度数字乘方
1
string bcpow ( string $left_operand , string $right_operand [, int $scale ] )

左操作数的右操作数次方运算, scale 用于设置结果中小数点后的小数位数。

1
2
3
#demo
echo bcpow(1.33, 2, 3); // 1.768
echo bcpow('4.2', '3', 2); // 74.08
7、bcpowmod — 求高精度数字乘方求模,数论里非常常用
1
string bcpowmod ( string $base , string $exponent , string $modulus [, int $scale = 0 ] )
1
2
3
$a = bcpowmod($x, $y, $mod, $scale);
$b = bcmod(bcpow($x, $y, $scale), $mod);
$a == $b;
8、bcscale — 配置默认小数点位数,相当于就是Linux bc中的 scale=
1
bool bcscale ( int $scale )

设置所有bc数学函数的未设定情况下得小数点保留位数. 全局默认值设置在 php.ini 中操作。

1
2
3
4
5
6
7
#demo
// default scale : 3
bcscale(3);
echo bcdiv('105', '6.55957'); // 16.007

// this is the same without bcscale()
echo bcdiv('105', '6.55957', 3); // 16.007
9、bcsqrt — 求高精度数字平方根
1
string bcsqrt ( string $operand [, int $scale ] )

返回操作数的二次方根, scale 用于设置结果中小数点后的小数位数。

10、bcsub — 将两个高精度数字相减
1
string bcsub ( string $left_operand , string $right_operand [, int $scale = int ] )

左操作数减去右操作数, scale 用于设置结果中小数点后的小数位数。