如何改变Magento订单价格?

时间:2015-07-02 07:59:37

标签: php magento casting

我在MagentoPayboxSOAP网络服务中付款时遇到了一个令人讨厌的错误,其想法如下:

  1. 付款以美分36.37美元= 3637cents(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;
    }
    
  4. 结果如下:

    3987
    1233
    1132
    After int conversion
    3986
    1233
    1132
    

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

1 个答案:

答案 0 :(得分:1)

您的算法总结如下:

  1. $price = 39.8699; // 39.869900000000001228
  2. round($price, 2) * 100; // 3986.9999999999995453
  3. (int)3986.9999999999995453; // 3986
  4. 除了最后一步,(int)投射被截断之外,你到处都是正确的四舍五入。舍入会更合适:

    round($price * 100)
    

    说,根本问题是计算机使用二进制逻辑并且通常将数字存储为基数2,而我们人类使用模糊逻辑并且更喜欢基数10.“小”整数没有太多问题因为有1到1 1对应但是在固定大小的基数2表示中存储任意基数10浮点数通常只是近似值。一个典型的例子是 1.1 ,它在基数10中有两位数,但在基数2中是periodic

    1.0001100110011001100110011001100110011001100110011001100110011001101...
    

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