Floating point 绕一圈浮子不起作用

Floating point 绕一圈浮子不起作用,floating-point,rounding,Floating Point,Rounding,我想知道为什么我的花车没有倒圆。 当我这样做时: $shipping_cost = float(57.599999999999994) round($shipping_cost, 2) 结果是:57.60000000000001 你知道为什么会这样吗? 它是否与服务器有关 感谢您这是由于大多数语言表示浮点值的方式不同造成的。尽管您没有指定您使用的语言或实现,但几乎可以肯定它使用的是IEEE-754 64位二进制浮点格式 在这种格式中,有限数表示为-253到+253(互斥)之间的整数f,两个提

我想知道为什么我的花车没有倒圆。 当我这样做时:

$shipping_cost = float(57.599999999999994) 
round($shipping_cost, 2)
结果是:57.60000000000001

你知道为什么会这样吗? 它是否与服务器有关


感谢您

这是由于大多数语言表示浮点值的方式不同造成的。

尽管您没有指定您使用的语言或实现,但几乎可以肯定它使用的是IEEE-754 64位二进制浮点格式

在这种格式中,有限数表示为-253到+253(互斥)之间的整数f,两个提升为-1074到971(包含)范围内的某个幂e。每个有限浮点值的形式为f•2e。(这些零件在编码存储时略有改动,但此描述在数学上是等效的。)

为了表示一个数字,有必要把它写成这种形式。例如,.75是3•2-2

值57.6不能准确地写入此表单中。最接近的可能值为8106479329266893•2-47=8106479329266893/140737488355328=57.60000000000001421085471520020037174224853515625。(不能再接近57.6,因为向分子中添加+1或-1会使值远离57.6,向指数中添加1会使分子超过253。因此,这是在浮点格式的范围内可以获得的最接近值。)

这就是
round(57.59999999994,2)
返回的结果


打印时,您使用的软件会省略一些数字。它似乎打印了足够的数字来唯一区分精确值(知道浮点格式的人可以使用显示的数字来计算精确值),但不足以完全显示精确值。

TL;DR:浮点数的数学设计有缺陷。在您的特定情况下,您应该使用
sprintf('%.2f',$cost)
,因为它将为您提供数字的字符串表示。最接近57.5999999999994的双精度数字正好是
57.59999999999999999439156588113919198513031005859375
。函数
round()
被赋予一项不可能完成的任务,即创建一个接近点后两位数的双精度。此双精度数字不存在,函数
round()
不应存在,因为它不可能完成其工作。它决定返回
57.60000000000001421085471520020037174224853515625
,最接近57.6的双精度。@raina77ow:考虑到浮点运算有缺陷,您会更改什么,特别是更改为什么?