我对此感到困惑并且不明白这里发生了什么,我在这里错过了一些可以解释的内容,我想了解并且无法在线找到解释它的资源或为什么它正在发生。
为什么以下等式在PHP中等于0.23999999999999而不是0.24。 我在这里不应用舍入,所有值都精确到小数点后两位。 那么为什么答案被填补所有这些0.009999999999?
return 65.00 + 0.03 - 0.90 - 50.00 - 13.89;
float(0.23999999999999)
我如何解决这个问题,或者让它准确显示从db中重新获取的内容而不是填充这些9#。
db中的所有值都存储为十进制10,2
答案 0 :(得分:1)
floating point numbers根据IEEE 574 standard在计算机中显示。
简单来说,小数是使用固定位数(数字)在计算机中编码的,就像我们在纸上写实数一样(我们使用base 10来编写数字,计算机使用base 2来处理它们。但并非所有小数都可以使用有限数字来编写(无论我们使用什么基数来编写它们)。实际上,他们中的大多数都有无限的代表性,只有一小部分是特权。
例如,1/3
是一个小数,无法使用十进制表示法精确表示。您可以将其写为0.3
,0.33
,0.333
或甚至0.3333333333333333
,但没有人可以写出所有数字。无论你写了多少3
,你都有一个停止的点,你写的数字<{>>不是1/3
的确切值,而是近似值(一个足够接近实际值的值)。
使用近似值时始终存在错误。它们很小而且可以忽略不计,但算术运算使它们累积,有时它们变得足够大,影响最终结果的正确性。
我们从小学就知道3 * 1/3 = 1
。
将上面显示的1/3
的表示乘以3
将产生0.9
,0.99
,0.999
和0.9999999999999999
。所有这些数字都接近1
,但它们都不等于1
。
糟糕,我们刚刚遇到了舍入错误!
在现实生活中,我们习惯于舍入我们使用的数字并忽略舍入误差。计算机以不同的方式工作。他们试图获得最好的结果,如果他们没有被告知这样做,他们就不会对这些数字进行舍入。
可以使用基数10中的有限位数精确表示的一些数字在基数2中具有无限表示。例如,1/10
在基数10中是0.1
但不能是用基数2中的有限位数表示。
事实上,只有分母a power of 2的分数在基数2中具有有限的表示。在基数10中,可用有限数字表示的数字是分母,其分母看起来像{{ 1}},其中2m*5n
和m
为non-negative integers。
n
uses the standard IEEE 574 floating point格式(与许多其他编程语言一样),这就是为什么代码中的数字在内部没有完全表示的原因。
您可以使用函数number_format()
或sprintf()
生成一个数字表示,其中包含您需要的位数。如果您需要的位数小于浮点表示的精度,PHP
将产生您期望的精确值。
如果您正在处理金钱,则始终使用number_format()
来获取您正在使用的金额的最终表示。
number_format($number, 2)
实现浮点数(单精度和双精度)和fixed-point types。 DECIMAL
列类型保证存储中数字的精确表示(使用列定义中指定的小数位数)以及使用它们的计算的确切结果。
然而,这种精确度会对处理速度造成损失,但总体而言,这些优势克服了这一缺点。
当然,当值加载到MySQL
进行处理或显示时,DECIMAL
数据类型的精确性和准确性会立即被破坏。