2

我需要在不四舍五入的情况下添加值(美元金额)。

例子:

添加的值来自$("input#lunchorder_item_price")并输出我的 subTotal。 2.95 + 2.95 + 2.45 = 8.35但我得到2.95 + 2.95 + 2.45 = 8.36

当前代码:

 function updateCartDisplayTotal() {
     $("div#ordersummary").remove();

     var subTotal = 0;
     $("input#lunchorder_item_price").each(function() {
        subTotal += parseFloat((this.value) + subTotal);
     });

     var orderSubtotal = subTotal.toFixed(2);
     var taxAmount = parseFloat(orderSubtotal*.0685)/*.toFixed(2)*/;
     var deliveryAmount = parseFloat(orderSubtotal*.10)/*.toFixed(2)*/;
     var orderTotal = (parseFloat(orderSubtotal) + parseFloat(taxAmount) + parseFloat(deliveryAmount))/*.toFixed(2)*/;

     var orderSummary = $("<div id=\"ordersummary\"><div>Subtotal: <strong>$"+ orderSubtotal +"</strong></div><div>Tax: <strong>$"+ taxAmount +"</strong></div><div>Delivery Fee: <strong>$"+ deliveryAmount +"</strong></div><div>Total: <strong>$"+ orderTotal +"</strong></div></div>");
     $(orderSummary).insertAfter("ul#cart-items");
  }

我的问题是我需要做些什么来防止这些四舍五入?任何帮助将不胜感激!

4

2 回答 2

3

问题的第一部分是浮点运算通常很烂。使用浮点数,您的示例...

2.95 + 2.95 + 2.45

... 实际上等于8.350000000000001.

您问题的第二部分是浏览器的实现不一致toFixed()(一些向上舍入,一些向下舍入,一些舍入到最接近的有效数字)。

以下是避免这些问题的一些技巧:

  1. toFixed()如果您需要跨浏览器的一致性(显然您在这里需要),请避免使用。
  2. 不要做任何中间 round/ floor/ ceil/等。操作 - 将其保存到最后。即,除了显示目的之外,不要乱用你的subTotal,等值。taxAmount
  3. 当您需要执行toFixed()类似操作时,通常有替代解决方案依赖于更准确和更一致地实施的操作(例如Math.round())。例如,要获取双精度数,可以执行以下操作:

    var total = 2.95 + 2.95 + 2.45;

    total = Math.round(total * 100) / 100;


这是使用上述建议的代码重构:

function toDoubleFixed(num) {
    var ret = '' + Math.round(num * 100) / 100;
    return ret.replace(/(\d+)?\.?(\d)?(\d)?/, function(match, l, r1, r2) {
        return (l||'0')+'.'+(r1||'0')+(r2||'0');
    });
}

function updateCartDisplayTotal() {
    $("div#ordersummary").remove();

    var subTotal = 0;
    $("input#lunchorder_item_price").each(function() {
        subTotal += +$(this).val();
    });

    var orderSubtotal = subTotal,
        taxAmount = orderSubtotal * .0685,
        deliveryAmount = orderSubtotal * .1,
        orderTotal = orderSubtotal + taxAmount + deliveryAmount;

    var $orderSummary = $("<div id=\"ordersummary\"><div>Subtotal: <strong>$" + toDoubleFixed(orderSubtotal) +"</strong></div><div>Tax: <strong>$"+ toDoubleFixed(taxAmount) +"</strong></div><div>Delivery Fee: <strong>$"+ toDoubleFixed(deliveryAmount) +"</strong></div><div>Total: <strong>$"+ toDoubleFixed(orderTotal) +"</strong></div></div>");

    $orderSummary.insertAfter("ul#cart-items");
}

我无法测试它,所以请告诉我它是如何工作的。另外,请注意我修改了你增加subTotal价值的方式,因为它以前看起来很不稳定......但也许我在那里遗漏了一些东西。

于 2013-04-10T14:14:06.310 回答
0

我通常将这样的值存储为便士金额。然后它更容易使用。

所以 4.95 美元变成 495 美元,16.32 美元变成 1632 美元。然后你可以使用完整的整数,只需在后面加上小数点。

如果您可以切换到此方法,我会推荐它。否则将字符串/浮点值转换为整数,根据需要对其进行数学运算,然后返回结果。

于 2015-11-08T19:50:02.113 回答