0

我仍然无法得到准确的结果。最大值是多少。如果我希望它尽可能准确,我应该显示多少小数?

一些代码(准备复制粘贴和测试):

// Test with 5 decimals 
$a = 0.00001;
echo bcadd($a,$a,5) . '<br/>';
echo bcadd($a,$a,6) . '<br/>';
echo number_format(bcadd($a,$a,5),5) . '<br/>';
echo number_format(bcadd($a,$a,5),6) . '<br/>';
echo bcadd(0.00001,0.00001,20) . '<br/>';
echo number_format(bcadd($a,$a,20),5) . '<br/>';
echo number_format(bcadd($a,$a,20),21) . '<br/><br/>';

/* Output:
0.00000
0.000000
0.00000
0.000000
0.00000000000000000000
0.00000
0.000000000000000000000
*/

// Test with 4 decimals
$a = 0.0001;
echo bcadd($a,$a,5) . '<br/>';
echo bcadd($a,$a,6) . '<br/>';
echo number_format(bcadd($a,$a,5),5) . '<br/>';
echo number_format(bcadd($a,$a,5),6) . '<br/>';
echo bcadd(0.00001,0.00001,20) . '<br/>'; // wtf? this outputs 0 too?
echo number_format(bcadd($a,$a,20),5) . '<br/>';
echo number_format(bcadd($a,$a,20),21) . '<br/>';

/* Output:
0.00020
0.000200
0.00020
0.000200
0.00000000000000000000
0.00020
0.000200000000000000010
*/

我应该推断答案是 4 吗?但是我在评论中仍然有问题

编辑:我认为没有人理解我的测试。我知道花车是不准确的。但一件事是 1 != 0.98990123,另一件事是 1 != 0.0000。如果我在 bc* 函数中将精度设置为 4,我希望得到至少 0.9899(如果完美答案是 1),而不是 0.0000。一件事是“对于无限精度来说并不完全准确”,另一件事是“完全没用”。

编辑 2:@Michael Borgwardt 有解决方案

4

4 回答 4

4

最大值是多少。如果我希望它尽可能准确,我应该显示多少小数?

您的问题始于尝试从浮点计算中获得准确的值。由于表示错误,您通常无法从浮点计算中获得准确的值。值 0.0001 不能以二进制浮点数精确表示,因此实际存储的值将与 0.0001 略有不同,这已经给您带来了不准确性。您应该期望最低有效数字不准确。显示更多小数不会使您的计算更加准确 - 它只会使固有的不准确性更加明显。

如果您需要准确性,您应该使用不同的数据类型(bcadd 确实接受字符串,但从浮点数到字符串的转换仍然会引入不准确性)或更改您的程序以允许与精确答案略有不同的答案。

如果您只想显示一个有用的答案,您可以将其显示为对您的应用程序有意义的精度。如果您正在计算设置烤箱以烹制火鸡的温度,那么将答案四舍五入到几个有效数字应该没问题。如果您正在进行科学计算,您可能希望显示具有 3、4 或更多有效数字的答案。如果您需要 100% 的准确度,那么您需要重新考虑您的设计。

于 2010-11-27T15:41:46.750 回答
3

“bcadd”需要三个参数。前两个是代表左右操作数的字符串和一个代表结果中小数位的整数。该函数输出一个字符串。尝试在第五个结果回显中使用字符串值而不是整数。

此外,关于浮点数的精度(来自 PHP.net):

浮点数的大小取决于平台,尽管最大约 1.8e308 和大约 14 位十进制数字的精度是一个常见值(64 位 IEEE 格式)。

于 2010-11-27T15:42:45.843 回答
2

问题的一个主要原因是您使用的是浮点文字。当代码被编译或解释并转换为二进制分数时,这会导致舍入错误。

那时,您已经迷路了——使用 bc 数学函数将无济于事。要正确使用它们,您必须使用字符串文字:

echo bcadd('0.00001','0.00001',20);

将打印:

0.00002000000000000000
于 2010-11-27T15:44:32.223 回答
-1

尝试使用 BCMath 库。它基本上将数字存储为字符串,但允许您对其进行算术运算。

处理非常大或非常小的数字

于 2010-11-27T15:43:32.850 回答