JavaScript中数值保留两位小数时4.225舍入异常问题求助
Ah, this is a classic floating-point precision gotcha in JavaScript! Let's break down why this happens and how to fix it for good.
The Root Cause
JavaScript uses the IEEE 754 double-precision standard to store numbers, which means some decimal values can't be represented exactly as binary fractions. For example, 4.225 isn't stored as exactly 4.225 under the hood—it's actually a value slightly less than that (think 4.224999999999999...). When Math.round() processes this, it sees a number closer to 4.22 than 4.23, hence the unexpected result.
Why do 3.225 and 5.225 work as expected? It's just luck of their binary representation—they happen to be stored as values slightly above their decimal equivalents, so rounding pushes them up to 3.23 and 5.23.
Reliable Fixes for Consistent Rounding
Here are three solid approaches to ensure you get the correct two-decimal rounding every time:
1. Adjust with Number.EPSILON (Lightweight & Effective)
Number.EPSILON is the smallest positive number in JavaScript that can create a distinct value when added to another number. Adding it to your input before rounding fixes the "slightly below" precision issue:
function roundToTwoDecimals(num) { return Math.round((num + Number.EPSILON) * 100) / 100; } // Test your values: console.log(roundToTwoDecimals(3.225)); // 3.23 console.log(roundToTwoDecimals(4.225)); // 4.23 console.log(roundToTwoDecimals(5.225)); // 5.23
2. String Manipulation Workaround
If you want to avoid floating-point quirks entirely, convert the number to a string with three decimal places, then round from there:
function roundToTwo(num) { // Convert to 3 decimal places to capture the third digit for rounding const temp = num.toFixed(3); // Round to two decimals return Math.round(parseFloat(temp) * 100) / 100; }
3. Use a Decimal Arithmetic Library (For Critical Calculations)
If you're working with financial or high-precision data, consider using a dedicated library designed for decimal arithmetic (like decimal.js). These libraries avoid IEEE 754 limitations entirely by handling numbers as decimal strings or integers under the hood.
Final Note
Floating-point precision issues aren't unique to JavaScript—they're a common pitfall in most programming languages. The Number.EPSILON trick is the simplest solution for most everyday cases, ensuring consistent rounding to two decimal places.
内容的提问来源于stack exchange,提问作者Rakesh

