PHP实现Excel STDEV函数时的小数精度差异问题
PHP实现Excel STDEV函数的精度差异问题解决
尝试用PHP实现Excel的STDEV函数时,发现结果和Excel存在细微差异:使用数组[1004, 1005, 1004]计算,PHP输出0.57735026918963,而Excel给出的结果是0.57735026918963400000。推测是浮点数精度或格式化问题导致,尝试number_format()和round()都没得到预期结果。
原PHP代码
$nums = [1004, 1005, 1004]; $sum = 0; for($i = 0; $i < count($nums); $i++) { $sum += $nums[$i]; } $media = ($sum / count($nums)); $sum2 = 0; for($i = 0 ; $i < count($nums); $i++) { $sum2+=($nums[$i]-$media)*($nums[$i]-$media); } $vari = ($sum2 / (count($nums) - 1)); $devStd = sqrt($vari); echo $devStd; // 输出 0.57735026918963
尝试过的无效方法
使用number_format()时参数错误,导致输出异常:
$devStd = number_format($devStd, 18, '.', false); // 错误输出:57735026918962573106
使用round()无论设置多少精度,输出始终为0.57735026918963。
解决方案
1. 修正number_format()参数
number_format()的第四个参数是千位分隔符,需传入空字符串而非false,修正后即可正确格式化:
$devStd = number_format($devStd, 18, '.', ''); echo $devStd; // 输出 0.57735026918962573106
这个结果和Excel的0.57735026918963400000差异源于浮点数内部表示的细微区别,属于正常精度范围。
2. 使用高精度计算扩展(BCMath)
若需要更贴近Excel的计算精度,建议使用PHP的BCMath扩展进行高精度运算,确保每一步计算都保留足够小数位:
$nums = [1004, 1005, 1004]; $count = count($nums); // 计算总和 $sum = array_sum($nums); // 计算平均值,保留20位精度 $media = bcdiv($sum, $count, 20); $sum2 = '0'; foreach ($nums as $num) { // 计算数值与平均值的差值 $diff = bcsub($num, $media, 20); // 计算差值的平方 $square = bcpow($diff, 2, 20); // 累加平方和 $sum2 = bcadd($sum2, $square, 20); } // 计算方差(除以n-1) $vari = bcdiv($sum2, bcsub($count, 1, 20), 20); // 计算标准差,保留20位精度 $devStd = bcsqrt($vari, 20); echo $devStd; // 输出 0.57735026918962576451
这个结果更接近Excel的输出,因为BCMath避免了普通浮点数运算的精度损失。
内容的提问来源于stack exchange,提问作者Alejandra Sandoval
相关产品推荐
相关产品推荐

