我正在尝试在 PHP 中执行 STDEV Excel 的函数,但我得到了不同的结果,也许这只是与小数或四舍五入相关的东西,因为结果非常相似,但是当我尝试获得与 Excel 上完全相同的数字时。我就是不能
我尝试过...
$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; // results 0.57735026918963
我在 PHP 中得到 0.57735026918963,但使用 Excel 得到相同的值,我得到 0.57735026918963400000,我知道你在想什么“只需使用 number_format() 或 round()”,但即使做类似的事情...
$devStd = number_format($devStd, 18, '.', false); // then I get 57735026918962573106
我得到 57735026918962573106 而不是 0.57735026918963400000
如果我使用 round,无论精度参数是什么,y 都会得到 0.57735026918963
谢谢
经检查正确的解析答案应该是1/sqrt(3)。
但是,1/3 是 IEEE 754 浮点二进制无法准确表示的数字之一,并且您对均值和平方和的计算是不完善的。
sqrt(3) = 5.77350269189625764509148780502e-1 (to 20 dp) from Maxima
我在OP引用的数字中留了一个缺口,以表明它们与上面参考正确值的偏差。
OP的答案是:
"I get 0.5773502691896 3 in PHP,"
该格式没有足够的小数位来明确显示 64 位双精度数。它需要 16 位或最好 18 位十进制数字才能显示。我怀疑 PHP 显示的“3”是从“2576”或“258”向上舍入的,在这种情况下,考虑到 IEEE754 的双重限制,它的表现令人钦佩。
but with same values using
"Excel I get 0.5773502691896 3400000" (sic)
后面的零非常具有误导性。 Excel 通过在显示的 15 位数字后截断为 0,隐藏了详细信息。您可以通过手动减去一些前导数字来强制它显示真实值。
您所拥有的Excel版本中的STDEV()是有缺陷请勿将其用作参考!
Excel 实际上将 sqrt(3) 设为 0.57735026918962625 868,当应用于 1004,1005,1004 时,我的 XL2021 副本中的 STDDEV() 版本也是如此。
OP 没有说明他使用的是哪个版本的 Excel,但通过我的 Excel 2021 STEDEV() 副本,给出了机器精度测试的正确答案。它还在 1000004,1000005,1000004 上得到相同的正确答案(这是对算法弱点的更严格的测试)。
如果您想在真正要求严格的情况下做得更好,那么请查找并实现Kahan summation,它允许在对现实世界中的浮点数求和时对舍入误差进行一些补偿。请注意,某些优化器可能会破坏它。