簡體   English   中英

Javascript加法使我的輸出超過2個小數位

[英]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.84數字添加尾隨0的點(如果需要,還加上點))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM