【问题标题】:bcmath seems to give the wrong answer to my calculationbcmath 似乎对我的计算给出了错误的答案
【发布时间】:2011-07-02 06:54:06
【问题描述】:

我不确定我做错了什么,但这个计算

bcscale(20);
echo bcmul(bcdiv('422218', '2388865'), '473');

回显“83.59999999999999999670”,但其他所有计算器都给我 83.6。

有没有办法解决这个问题,还是 bcmath 的缺陷?

【问题讨论】:

  • 这似乎是一个解释性的例子。如果这是你想要的,你为什么不重新排序操作或简单地使用普通的 PHP 浮点算法?

标签: php bcmath


【解决方案1】:

您看到此结果的原因是因为您首先执行了除法。

师给你:

422218/2388865
0.17674418604651162790697674418604651163

但是你要求 20 位数字,所以它变成了0.1767441860465116279。鉴于此, bc 现在为您提供正确的结果:

0.1767441860465116279*473
83.5999999999999999967

在这种情况下,“解决方案” 将是首先执行乘法(这给您“仅”9 个数字),然后执行除法:

bcscale(20);
echo bcdiv(bcmul('422218','473'),'2388865');
83.60000000000000000000

【讨论】:

  • 是的!没有诡计的适当解决方案。谢谢!现在我想我会去复习我的数学:)
【解决方案2】:

bcmath 函数使用任意 精度算术。计算不是 100% 精确的 - 它们只是按照您的要求精确(您要求 20 级)。由于计算不精确,您不能总是期望答案是精确的。

你说你的计算器在这种情况下给了你正确的答案。但是假设它也使用任意精度算术(大多数都使用)它会在其他情况下给你错误的答案。一些计算器通过以比它们显示的更高的精度(例如额外的两位数)进行计算来隐藏它们的不准确性。如果您在错误累积的地方执行计算,它最终会在显示中显示。

【讨论】:

  • 是的,这很有意义,感谢您让我疲惫的大脑恢复正常!
【解决方案3】:

您指定的精度(20 位)超出了大多数计算器的精度。所以他们会四舍五入,最有可能是 10 或 15 位数,给出 83.5999...99,四舍五入为 83.6。

【讨论】:

    【解决方案4】:

    BCMath 为您提供准确的结果。如果您需要其他数字“形式”,请使用round() 等函数进行更改:

    http://php.net/manual/en/function.round.php

    例如:

    echo round(bcmul(bcdiv('422218', '2388865'), '473'), 1);
    

    会给你 83.6。

    【讨论】:

    • 确切的结果是418/583.6
    • “精确”结果是指计算机计算出的精确数字——有人说它的精度有限,所以结果也将是“有限的”。
    • @TomaszKowalczyk 我知道我做错了什么,我很可能会使用类似的方法来解决它,在另一个问题 link 中找到了一个不错的 bcround() 函数,我想我会用它降低我显示的数字的精度。
    • @Tomasz 我认为这个答案具有误导性并隐藏了潜在的问题。例如,在这种情况下,您可以交换 div 和 mul 的顺序并获得准确、正确的结果。请,因为这是公认的答案,请至少对此发表评论。
    • @Eelvex 你是什么意思我应该运行 473*(422218/2388865) ?这似乎给了我与上面相同的答案..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 2017-04-29
    • 2023-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多