为什么这些值没有正确求和?

时间:2015-03-27 11:51:40

标签: php mysql

我对此感到困惑并且不明白这里发生了什么,我在这里错过了一些可以解释的内容,我想了解并且无法在线找到解释它的资源或为什么它正在发生。

为什么以下等式在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

1 个答案:

答案 0 :(得分:1)

floating point numbers根据IEEE 574 standard在计算机中显示。

简单来说,小数是使用固定位数(数字)在计算机中编码的,就像我们在纸上写实数一样(我们使用base 10来编写数字,计算机使用base 2来处理它们。但并非所有小数都可以使用有限数字来编写(无论我们使用什么基数来编写它们)。实际上,他们中的大多数都有无限的代表性,只有一小部分是特权。

例如,1/3是一个小数,无法使用十进制表示法精确表示。您可以将其写为0.30.330.333或甚至0.3333333333333333,但没有人可以写出所有数字。无论你写了多少3,你都有一个停止的点,你写的数字<{>>不是1/3的确切值,而是近似值(一个足够接近实际值的值)。

使用近似值时始终存在错误。它们很小而且可以忽略不计,但算术运算使它们累积,有时它们变得足够大,影响最终结果的正确性。

我们从小学就知道3 * 1/3 = 1。 将上面显示的1/3的表示乘以3将产生0.90.990.9990.9999999999999999。所有这些数字都接近1,但它们都不等于1

糟糕,我们刚刚遇到了舍入错误!

在现实生活中,我们习惯于舍入我们使用的数字并忽略舍入误差。计算机以不同的方式工作。他们试图获得最好的结果,如果他们没有被告知这样做,他们就不会对这些数字进行舍入。

可以使用基数10中的有限位数精确表示的一些数字在基数2中具有无限表示。例如,1/10在基数10中是0.1但不能是用基数2中的有限位数表示。

事实上,只有分母a power of 2的分数在基数2中具有有限的表示。在基数10中,可用有限数字表示的数字是分母,其分母看起来像{{ 1}},其中2m*5nmnon-negative integers

为什么是我?

n uses the standard IEEE 574 floating point格式(与许多其他编程语言一样),这就是为什么代码中的数字在内部没有完全表示的原因。

您可以使用函数number_format()sprintf()生成一个数字表示,其中包含您需要的位数。如果您需要的位数小于浮点表示的精度,PHP将产生您期望的精确值

如果您正在处理金钱,则始终使用number_format()来获取您正在使用的金额的最终表示。

另一方面,

number_format($number, 2)实现浮点数(单精度和双精度)和fixed-point typesDECIMAL列类型保证存储中数字的精确表示(使用列定义中指定的小数位数)以及使用它们的计算的确切结果。

然而,这种精确度会对处理速度造成损失,但总体而言,这些优势克服了这一缺点。

当然,当值加载到MySQL进行处理或显示时,DECIMAL数据类型的精确性和准确性会立即被破坏。