四捨五入 - 在 JavaScript 中將數字格式化為正好兩位小數
我有這行程式碼會將我的數字四捨五入到小數點後兩位。但我得到的數字像這樣:10.8、2.4 等等。這些不是我心目中的兩位小數,那我該如何改進以下程式碼呢?
Math.round(price*Math.pow(10,2))/Math.pow(10,2);
我想要像 10.80、2.40 這樣的數字。使用 jQuery 對我來說沒問題。
答案#1
要使用固定小數點表示法格式化數字,你可以簡單地使用 toFixed 方法:
(10.8).toFixed(2); // "10.80"
var num = 2.4;
alert(num.toFixed(2)); // "2.40"
請注意,toFixed() 會回傳一個字串。
重要:請注意,toFixed 在 90% 的情況下不會進行四捨五入,它會返回四捨五入的值,但在許多情況下,它不起作用。
例如:
2.005.toFixed(2) === "2.00"更新:
如今,你可以使用 Intl.NumberFormat 建構函式。它是 ECMAScript 國際化 API 規範(ECMA402)的一部分。它有相當好的瀏覽器支援,包括 IE11,並且在 Node.js 中也完全支援。
const formatter = new Intl.NumberFormat('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
console.log(formatter.format(2.005)); // "2.01"
console.log(formatter.format(1.345)); // "1.35"你也可以使用 toLocaleString 方法,它內部將使用 Intl API:
const format = (num, decimals) => num.toLocaleString('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
console.log(format(2.005)); // "2.01"
console.log(format(1.345)); // "1.35"此 API 還為您提供了多種格式化選項,例如千位分隔符、貨幣符號等。
答案#2
這是一個舊話題,但仍然是 Google 搜尋結果中的熱門,且提供的解決方案都存在相同的浮點數小數問題。以下是我使用的(非常通用的)函數,感謝 MDN:
function round(value, exp) {
if (typeof exp === 'undefined' || +exp === 0)
return Math.round(value);
value = +value;
exp = +exp;
if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
return NaN;
// Shift
value = value.toString().split('e');
value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));
// Shift back
value = value.toString().split('e');
return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}
如我們所見,我們沒有遇到這些問題:
round(1.275, 2); // Returns 1.28
round(1.27499, 2); // Returns 1.27
這種泛型性還提供了一些很酷的功能:
round(1234.5678, -2); // Returns 1200
round(1.2345678e+2, 2); // Returns 123.46
round("123.45"); // Returns 123
現在,要回答發帖者的問題,必須輸入:
round(10.8034, 2).toFixed(2); // Returns "10.80"
round(10.8, 2).toFixed(2); // Returns "10.80"
或者,對於一個更簡潔、較不通用的函數:
function round2Fixed(value) {
value = +value;
if (isNaN(value))
return NaN;
// Shift
value = value.toString().split('e');
value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + 2) : 2)));
// Shift back
value = value.toString().split('e');
return (+(value[0] + 'e' + (value[1] ? (+value[1] - 2) : -2))).toFixed(2);
}
你可以用以下方式呼叫它:
round2Fixed(10.8034); // Returns "10.80"
round2Fixed(10.8); // Returns "10.80"
各種範例和測試(感謝 @t-j-crowder!):
function round(value, exp) {
if (typeof exp === 'undefined' || +exp === 0)
return Math.round(value);
value = +value;
exp = +exp;
if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
return NaN;
// Shift
value = value.toString().split('e');
value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));
// Shift back
value = value.toString().split('e');
return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}
function naive(value, exp) {
if (!exp) {
return Math.round(value);
}
var pow = Math.pow(10, exp);
return Math.round(value * pow) / pow;
}
function test(val, places) {
subtest(val, places);
val = typeof val === "string" ? "-" + val : -val;
subtest(val, places);
}
function subtest(val, places) {
var placesOrZero = places || 0;
var naiveResult = naive(val, places);
var roundResult = round(val, places);
if (placesOrZero >= 0) {
naiveResult = naiveResult.toFixed(placesOrZero);
roundResult = roundResult.toFixed(placesOrZero);
} else {
naiveResult = naiveResult.toString();
roundResult = roundResult.toString();
}
$("<tr>")
.append($("<td>").text(JSON.stringify(val)))
.append($("<td>").text(placesOrZero))
.append($("<td>").text(naiveResult))
.append($("<td>").text(roundResult))
.appendTo("#results");
}
test(0.565, 2);
test(0.575, 2);
test(0.585, 2);
test(1.275, 2);
test(1.27499, 2);
test(1234.5678, -2);
test(1.2345678e+2, 2);
test("123.45");
test(10.8034, 2);
test(10.8, 2);
test(1.005, 2);
test(1.0005, 2);table {
border-collapse: collapse;
}
table, td, th {
border: 1px solid #ddd;
}
td, th {
padding: 4px;
}
th {
font-weight: normal;
font-family: sans-serif;
}
td {
font-family: monospace;
}<table>
<thead>
<tr>
<th>Input</th>
<th>Places</th>
<th>Naive</th>
<th>Thorough</th>
</tr>
</thead>
<tbody id="results">
</tbody>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>答案#3
我通常會將這個加入我的個人資料庫,經過一些建議並使用 @TIMINeutron 的解決方案,然後將其調整以適應小數長度後,這個最適合:
function precise_round(num, decimals) {
var t = Math.pow(10, decimals);
return (Math.round((num * t) + (decimals>0?1:0)*(Math.sign(num) * (10 / Math.pow(100, decimals)))) / t).toFixed(decimals);
}
將適用於所報告的例外情況。
答案#4
快速且簡單
parseFloat(number.toFixed(2))
例子
let number = 2.55435930
let roundedString = number.toFixed(2) // "2.55"
let twoDecimalsNumber = parseFloat(roundedString) // 2.55
let directly = parseFloat(number.toFixed(2)) // 2.55
答案#5
確保你得到一個帶有兩位小數的數字的其中一種方法:
(Math.round(num*100)/100).toFixed(2)
如果這會導致四捨五入錯誤,你可以使用以下方法,就像 James 在他的評論中解釋的那樣:
(Math.round((num * 1000)/10)/100).toFixed(2)
答案#6
我不知道為什麼我不能對之前的回答添加評論(也許我真的看不見,我不知道),但是我想出了一個使用 @Miguel 的回答的解決方案:
function precise_round(num,decimals) {
return Math.round(num*Math.pow(10, decimals)) / Math.pow(10, decimals);
}
以及它的兩條評論(來自 @bighostkim 和 @Imre):
precise_round(1.275,2)無法返回 1.28 的問題- 在使用
precise_round(6,2)時出現問題,沒有返回 6.00(如他所希望的)。
我的最終方案如下:
function precise_round(num,decimals) {
var sign = num >= 0 ? 1 : -1;
return (Math.round((num*Math.pow(10,decimals)) + (sign*0.001)) / Math.pow(10,decimals)).toFixed(decimals);
}
如你所見,我必須加入一點“修正”(它實際上不是修正,但由於 Math.round 是有損的 —— 你可以在 jsfiddle.net 上檢查 —— 這是我唯一知道的“修復”方法)。它會在已經補零的數字上加上 0.001,所以它相當於在小數點右側添加了一個 1,後面跟著三個 0。所以使用起來應該是安全的。
之後我加上了 .toFixed(decimal),以始終以正確的格式輸出數字(具有正確的小數位數)。
大概就是這樣。好好使用它吧 ;)
編輯:為負數的「更正」新增了功能。
答案#7
toFixed(n) 提供小數點後 n 位長度;toPrecision(x) 提供總長度為 x。
使用以下方法
// Example: toPrecision(4) when the number has 7 digits (3 before, 4 after)
// It will round to the tenths place
num = 500.2349;
result = num.toPrecision(4); // result will equal 500.2
如果你想要這個數字被固定,請使用
result = num.toFixed(2);
