Math
计算相关
高精度计算问题
var_dump(intval(0.58 * 100)); // int(57)
var_dump((0.1 + 0.7) == 0.8); // false
说明:如果用php的+-*/计算浮点数的时候,可能会遇到一些计算结果错误的问题,比如上面 的 echo intval( 0.58*100 );会打印57,而不是58,这个其实是计算机底层二进制无法精确表示浮点数的一个bug,是跨语言的,我用python也遇到这个问题。所以基本上大部分语言都提供了精准计算的类库或函数库,比如php有BC高精确度函数库。
// 配置默认小数点位数,相当于就是Linux bc中的”scale=”
bcscale(2);
// 高精度加减乘除
var_dump(bcadd(0.58, 0.01, 2)); // string(4) "0.59"
var_dump(bcsub(0.58, 0.01, 2)); // string(4) "0.57"
var_dump(bcmul(0.58, 100, 2)); // string(5) "58.00"
var_dump(bcdiv(58, 100, 2)); // string(4) "0.58"
// 比较两个高精度数字,返回-1, 0, 1
var_dump(bccomp('1', '2')); // int(-1)
// 求高精度数字余数
var_dump(bcmod('2', '4')); // string(1) "2"
// 求高精度数字乘方
var_dump(bcpow('4.2', '3', 2)); // string(5) "74.08"
// 求高精度数字乘方求模,数论里非常常用
var_dump(bcpowmod('2', '3', 16)); // string(1) "8"
// 求高精度数字平方根
var_dump(bcsqrt('4', 2)); // string(4) "2.00"
pwo
返回参数的几次方(方便记忆:怕我)
echo pow(2, 3); // 8
sqrt
返回参数的平方根(方便记忆:是抢人头)
echo sqrt(9); // 3
intdiv
用来进行整数的除法运算。(PHP7)
var_dump(intdiv(10, 3)); // 3
进制转换
decbin
十进制转二进制、bindev // 二进制转十进制
echo decbin(10); // 1010
echo bindec(1010); // 10
十进制转62进制以内的任意进制
自增主键,看起来像是随机字母+数字
慎用:15位数字以上会有问题
// 十进制转62进制以内的任意进制「最高支持62位」
function systemConvert($int, $format = 58): string
{
$dic = [
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D',
'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z'
];
$arr = [];
$loop = true;
while ($loop) {
$int = scToNum($int);
$arr[] = $dic[bcmod($int, $format)];
$int = floor(bcdiv($int, $format));
if ($int == 0) {
$loop = false;
}
}
return implode('', array_reverse($arr));
}
function scToNum($num, $double = 0){
if(false !== stripos($num, "e")){
$a = explode("e",strtolower($num));
return bcmul($a[0], bcpow(10, $a[1], $double), $double);
}else{
return $num;
}
}
echo systemConvert('999999999999999999');