PHP添加2个小数点数(金钱)会导致总金额错误

时间:2012-06-20 07:35:34

标签: php

我的MySQL数据库中有一个客户发票表,其中有一个名为price的DECIMAL(10,2)字段。

在php中获取这些值并计算总和时,

ex:在剧本中

$totalAmount = 0; // initialised them to 

   while(records){              

       $amount = $inv_amount - ($pay_amount + $onamount); //float i guess. 2.22, 14.22
       $totalAmount = $totalAmount + $amount; //float i guess. 2.22, 14.22 ..etc

    }

echo $totalAmount;它在最终数量0.01时有轻微错误但是当处理大约20,000的大数据集时,这个错误变得非常可观,例如200 +

在使用PHP中的这些数字处理价格时,最安全的方法是什么?或者我最终会遇到潜在的舍入错误以及使用浮点数据类型时常见的问题吗?

正在使用

round 
number_format

是此类财务应用程序最合适的解决方案吗?

7 个答案:

答案 0 :(得分:8)

实际上,浮点数并不准确 以分为单位计算(乘以100并以整数计算),或使用BC Math以字符串计算。

答案 1 :(得分:3)

试试这个:

$totalAmount = number_format($totalAmount, 2, '.', '');

答案 2 :(得分:2)

如果您需要2位小数的准确度:

  1. 将值乘以100
  2. 执行您的操作
  3. 除以100,并在适当情况下使用number_format

答案 3 :(得分:0)

你试过

吗?
round(totalAmount, 2, PHP_ROUND_HALF_ODD);

它应该看到最后一个十进制数 - 如果它是奇数 - 向下舍入,如果均匀 - 向上

答案 4 :(得分:0)

嗯,首先,为什么在php循环中总结你可以在mysql中做到这一点?此外,只需使用整数乘以100,然后在需要最终结果时除以100。

答案 5 :(得分:0)

我建议使用查询或视图对SQL Level进行计算。

首先,在PHP上使用64位整数是有风险的,因为;在溢出时,它切换到浮动,你会失去精度。当它的钱,问题更严重。你应该用sql实际计算一个列,然后从那里获取值。金钱是一种很长的类型,它经常会转换为浮动的PHP,你的人将失去或赢取一些美分,这取决于php引擎的情绪。您不能在php上使用十进制类型,即使您乘以100并将其保持为整数,带溢出的长数字也将自动转换为浮点数。如果要使用十进制数字或将字段转换为int,请在MYSQL上计算您的值。

如果你的服务器有一个32位的cpu,那么WORD长度是32位,所以php引擎中的整数是32位整数。这使得溢出的可能性更高。在64位系统上,您可以更舒适地工作。

在这种情况下,对货币价值使用圆函数是荒谬和不专业的。不要这样做。

阅读this document将对您有所帮助。

php文档of integers says

  

整数溢出

     

如果PHP遇到超出整数类型边界的数字,则会将其解释为float。此外,导致超出整数类型边界的数字的操作将返回浮点数。

SQL级别的计算将确保货币类型的精确度。将钱类型转换为php将导致浮点值,并且您可以将它乘以100然后除以100但是它会再次增加溢出值,因为php将使用32位浮点数进行存储。如果您使用32位浮点数,为什么数据字段为十进制?如果你这样做,那就不一致了。一个32位的数字我已经不是那么大了,一个32位的浮点数会在浮点数上失去一些容量,所以当你乘以100时它更有可能达到容量。

使用SQL

答案 6 :(得分:0)

您可以使用number_format

Ex :(两位小数点)

$number = 12345.5667;
echo $result = number_format($number, 2);

或者您可以在MySql中使用round函数:

ROUND(number,2)