浮点精度问题是否仅影响计算?

时间:2013-02-18 04:13:44

标签: php floating-point

我有一些价格和折扣金额将存储在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。所以,即使在四舍五入到小数点后两位,我也得到不同的数字。

1 个答案:

答案 0 :(得分:2)

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

当源文本由编译器或解释器解释或在运行时解析时,可能会发生转换,但它确实发生并且可能会出现舍入错误。

(您的问题断言,使用浮点数进行比较和计算会产生意外结果。只有当您不希望操作符合这些操作的规范时才会出现这种情况。您可以通过学习规范来避免意外结果,因此学习期待什么。)