You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 04:25:04