[英]Javascript addition gives me an output of more than 2 decimal places
我有一个对象,该对象具有mySql上的数据类型Decimal(10,2)的money属性。
我的JavaScript发出了http请求来检索这些值,然后在javascript函数中处理数据,以将所有值加到一个$ scope中:
$scope.expected = 0;
for(var k = 0; k < collection.length; k++)
{
$scope.expected += Number(collection[k].price);
}
price
是包含125.89
作为数据库中的值的货币值。 迭代进行31次迭代,因为collection.length
返回31
。
我使用了Number
参考,因为它以字符串开头。
当循环结束时,我得到的总和是: 3902.589999999999
但是我想要的只是3902.58
因为这是金钱,它必须是精确的表示形式。 我研究了一下,社区似乎同意使用toFixed(2)
但据我了解, toFixed(2)
将数字四舍五入,因为此操作涉及现金,所以我不想这样做。
有没有一种方法可以保留小数点后两位而不舍入?
在整个循环中,我还保存了console.log的日志。 结果如下:
125.89
251.78
377.67
503.56
629.45
755.34
881.23
1007.12
1133.01
1258.9
1384.7900000000002
1510.6800000000003
1636.5700000000004
1762.4600000000005
1888.3500000000006
2014.2400000000007
2140.1300000000006
2266.0200000000004
2391.9100000000003
2517.8
2643.69
2769.58
2895.47
3021.3599999999997
3147.2499999999995
3273.1399999999994
3399.0299999999993
3524.919999999999
3650.809999999999
3776.699999999999
3902.589999999999
在这里,我为您的问题创建了代码:
for(var k = 0; k < data.length; k++)
{
var num2 = data[k].toString().split('.');
if(typeof num2[1] != 'undefined')
{
num2[1] = num2[1].toString().substring(0,2);
data[k] = num2[0] + "." + num2[1];
}
console.log(Number(data[k]));
}
从您的帖子中看来,您正在处理正数。
如果要截断最终结果,可以通过像这样调用Math.floor来实现
$scope.expected = Math.floor($scope.expected * 100)/100;
但是,另一方面,如果您想在求和之前将每个数字截断为两位小数,则可以使用以下命令
$scope.expected = 0;
for(var k = 0; k < collection.length; k++)
{
$scope.expected += Math.floor(Number(collection[k].price) * 100) / 100;
}
请注意,这仅在您所有数字均为正数(大于或等于零)时起作用。
如果期望负数,则可以设计一个函数,如下所示:
truncateNumber = function (number) {
if(number < 0){
return Math.ceil(number * 100) / 100;
}else{
return Math.floor(number * 100) / 100;
}
};
例
使用任一
$scope.expected = truncateNumber($scope.expected);
要么
for(var k = 0; k < collection.length; k++)
{
$scope.expected += truncateNumber(Number(collection[k].price));
}
由于浮点数在javascript中的工作方式,因此您所描述的行为是可以预期的。 您需要的解决方案取决于所需的准确范围:如果需要更大的数字范围,则可以使用javascript获取,应该查看大数字库。
由于Math.pow(2, 53) === 9007199254740992
是javascript中最大的可直接表示的整数,因此您可以将该范围减小100倍,从而获得2个小数位的精度。 那将使您的正数范围为[0,90071992547409]。
我不认为你想要3902.58
; 您可能想要: 3902.59
(= 125.89 * 31)
假设您输入的最大精度为2位小数,并且没有负值:
<xmp id="dbg"></xmp> <script>// create $scope, collection and get debug output element for example: for(var dbg=document.getElementById('dbg'), $scope={}, L=31, collection=new Array(L); L--; collection[L]={price:'125.89'}); // ========== ANSWER BEGINS HERE: ========== $scope.expected = 0; for(var k = 0; k < collection.length; k++){ $scope.expected += Number(collection[k].price)*100; //increase precision //added debug line meant to resemble the debug listing in your question: dbg.innerHTML+=($scope.expected / 100).toFixed(2) + '\\n' ; } // maintain precision internally and only round when needed (like before output) // flooring your total is optional (not needed when you can guarantee // no more than 2 decimals at the input-side). // divide by 100 before output // then use toFixed to convert the number to string // AND append dot/decimals when needed dbg.innerHTML+='\\nTotal: ' + (Math.floor($scope.expected) / 100).toFixed(2); </script>
不要被toFixed
抛弃:我们使用它来确保2个小数(换句话说,为8.8
或4
数字添加尾随0
的点(如果需要,还加上点))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.