2013-02-18 109 views
2

我有一些价格和折扣金额将存储在PHP代码中的配置变量。我想知道是否需要将它们存储为字符串。浮点精度问题只影响计算吗?

例如,是否安全地执行以下操作?

$price = 14.95; 
$volume_discount = 0.3; 

还是应该将它们存储为字符串?

$price = '14.95'; 
$volume_discount = '0.3'; 

我知道,比较浮点数和用浮点数进行计算可能会产生意想不到的结果,除非使用BC Math。但我想知道只是按原样打印出存储的值。我试着回应浮动版本,并按预期显示,但我想知道这是否可靠。

注意:我用预计解释外行人所期待的术语。正如Eric指出的那样,精确的十进制浮点数实际上是而不是的预期结果。

编辑:我现在关心的代码检查数量并确定是否应该应用折扣。然后执行以下计算:

$price -= round($price * $volume_discount, 2); 

我通常使用number_format格式化价格显示,但我注释掉的格式为我的测试。到目前为止,无论价格或折扣价值,PHP一直给我期望的结果。然而,JavaScript并不总是给我想要的结果。这就是让我再次查看我的PHP代码的原因。

显然,我会调整JavaScript,因为那是错误出现的位置,但我试图决定是否需要重构我的PHP代码。

说明问题的数字是149.95 * 0.3。 PHP显示44.985和JavaScript显示44.98499999999999。所以,即使在四舍五入到小数点后两位,我也会得到不同的数字。

+0

取决于您将使用的代码。 – 2013-02-18 06:01:11

回答

2

解读十进制数字“14.95”并将其存储在一个二进制浮点对象需要浮点运算:转换从十进制到二进制浮点。因此,这是一个浮点运算,并且会出现舍入误差。

,当源文本由编译器或解释在运行时解释转换可能发生,但它确实发生了,并受舍入误差。 (你的问题断言,用浮点数进行比较和计算会产生意想不到的结果,只有当你不希望操作遵守这些操作的规范时才是这样,你可以通过学习规范和因此学习期望什么。)

+0

在这种情况下,精确显示的值是否恰巧?我的脚本一直在用正常的数学方法进行价格计算,我没有注意到任何舍入错误。只是现在我正在添加JavaScript计算,我注意到了一个差异。 JavaScipt有四舍五入错误,而不是PHP。 – toxalot 2013-02-18 06:03:29

+0

@toxalot:您还没有表现出你如何显示数字。当执行中等数量的操作并且数字以仅显示少数数字的格式显示时,通常四舍五入误差是不可见的,因为它们没有足够(从理想的数学结果)改变数值以改变显示的值。但是,使用少量值甚至很多值进行测试并不足以保证其他值的错误不会导致此类更改。一般来说,确定长序列操作的良好误差是一个难题。 – 2013-02-18 06:09:51

+0

所以我想我到目前为止已经很幸运了,而且我需要决定舍入误差是多么重要。 – toxalot 2013-02-18 06:48:13