如何转换以美分为单位的Magento订单价格


How to transform the Magento order price in cents?

我在MagentoPayboxSOAP web服务中有一个严重的支付错误,其想法如下:

  1. 付款单位为分$36.37=3637元(Paybox-API)
  2. 我想做的是通过以下方式将我的订单价格转换为美分:

    $cents = $order->getBaseGrandTotal() * 100;

  3. 此外,我有一个web服务SOAP(严格类型),它respond这个$cents的数量,但它将其与(int)协调,然后神奇的是,有时转换的数量不是预期的数量,转换的结果不到一美分,在我的情况下可能是3736

    $prices = array(39.8699, 12.3299, 11.3211);
    foreach ($prices as $price) {
        $stuff = round($price, 2) * 100;
        echo $stuff . PHP_EOL;
    }
    echo "After int conversion" . PHP_EOL;
    foreach ($prices as $price) {
        $stuff = (int) (round($price, 2) * 100);
        echo $stuff . PHP_EOL;
    }
    

结果如下:

3987
1233
1132
After int conversion
3986
1233
1132

问题有没有办法修复这个bug,它似乎是一个php bug?

您的算法总结如下:

  1. $price = 39.8699; // 39.869900000000001228
  2. round($price, 2) * 100; // 3986.9999999999995453
  3. (int)3986.9999999999995453; // 3986

除了在最后一步中,(int)的投射会截断外,您在所有地方都是正确的四舍五入。四舍五入更合适:

round($price * 100)

也就是说,根本问题是计算机使用二进制逻辑,通常将数字存储为基数2,而我们人类使用模糊逻辑,更喜欢基数10。"小"整数没有太大问题,因为存在1到1的对应关系,但将任意基数为10的浮点数存储在固定大小的基数为2的表示中通常只是一种近似。一个经典的例子是1.1,它在10进制中有两个数字,但在2进制中是周期性的:

1.0001100110011001100110011001100110011001100110011001100110011001101...

这就是为什么常见的建议包括在可用时使用精确的数据类型(关系数据库中的DECIMAL,客户端代码中的整数)。