我处理mysql数据库中的利率。它们存储为双精度数,通常为千分之一小数位(例如:4.657)但有时更多。有时候,我只需要将这些报告到百分之一的地方(例如:4.65),但我不能围绕这些 - 我需要将它们截断。所以,如果我在数据库中的利率为5.6575%,我需要得到5.65%,而不是5.66%。
一般来说,TRUNCATE(int_rate,2)可以正常工作。到目前为止,这对我没有任何问题。
我遇到以下利率问题:8.0300%,8.0400%,9.0300%,9.0400%,10.0300%,10.0400%......等。只有当利率超过8%且3或者4是百分之一,其余是0。
如果8.0是在DB中,当我执行TRUNCATE(int_rate,2)时,它返回8.03。如果我尝试使用FLOOR:FLOOR(int_rate * 100)/ 100
,它也会这样做如果我对数字进行硬编码而不是从数据库中提取数字,则会正确截断:TRUNCATE(8.04,2)或TRUNCATE(8.0400,2)会按预期返回8.04。
4.0400%工作正常! 8.0600%也是如此!为什么要给出这些结果?此外,如果有人可以建议如何在没有此错误的情况下执行此操作,那将是惊人的!
MySql:5.0.95
答案 0 :(得分:0)
浮点数的精度有限。虽然它取决于系统,但PHP通常使用IEEE 754双精度格式,由于舍入的顺序为1.11e-16,因此会产生最大的相对误差。非基本算术运算可能会产生更大的误差,当然,当复合多个运算时,必须考虑误差传播。
此外,基本10中的浮点数精确表示的有理数,如0.1或0.7,没有精确表示为基数2中的浮点数,无论尾数的大小如何,它都在内部使用。因此,它们不能在没有很小精度损失的情况下转换为它们的内部二进制对应物。这可能会导致令人困惑的结果:例如,floor((0.1 + 0.7)* 10)通常会返回7而不是预期的8,因为内部表示将类似于7.9999999999999991118 ....
现在可能的修复:您是否尝试过ROUND而不是TRUNCATE?