2013-04-10 45 views
2

我需要在不舍入值的情况下添加值(美元金额)。将价值(美元金额)一起添加并防止舍入

示例:正在添加

的值来自$("input#lunchorder_item_price")和输出我的小计。 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"); 
    } 

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

+0

它也取决于浏览器,Chrome例如** rounds ** toFixed。这很有可能是你的orderSubtotal被四舍五入的轻微 – 2013-04-10 14:06:31

+0

我正在使用chrome ...但是有没有一种方法可以确保它的行为符合所需的全面性,而不管浏览器如何。 – philecker 2013-04-10 14:08:26

回答

3

问题的第一部分是floating point arithmetic generally sucks。使用花车,你的例子...

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"); 
} 

我无法测试它,所以请让我知道它是如何运作的。另外,请注意,我修改了如何增加您的价值,因为它看起来很不稳定......但也许我错过了那里的一些东西。

+0

关于如何实现我的目标的想法呢? – philecker 2013-04-10 14:21:10

+0

步骤1,2和3 :) 1)根本不要使用'toFixed()'。 2)不要做任何舍去或其他操作,除了当你显示数值时(除非你以后再使用这个值)。 3)为了显示的目的,使用我的'Math.round()'技巧而不是'toFixed()'。 – jmar777 2013-04-10 14:23:53

+0

嗯,我想这就是为什么我问这个问题,我不明白如何实现,而不使用。 '.toFixed','parseFloat'等...如果我删除'parseFloat',我得到的是2.452.952.95,而不是将值加在一起。 – philecker 2013-04-10 14:31:54

0

我通常会将这种值存储为一分钱。然后更容易处理。

所以4.95美元成为495和16.32美元成为1632.然后,您可以使用完整整数,并简单地加上小数点后。

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