Math.round 详解
Math.round() 是 JavaScript 内置的数学函数,用于返回一个数字四舍五入后的最接近的整数。
1. 语法
javascript
Math.round(x)
- 参数 :
x-- 一个数字(会被隐式转换为 Number 类型)。 - 返回值 :给定数字四舍五入后的整数值 (
Number类型)。
2. 舍入规则(标准四舍五入)
- 如果小数部分 ≥ 0.5,则向正无穷方向舍入(进一)。
- 如果小数部分 < 0.5,则向负无穷方向舍入(舍去)。
注意 :这是数学上标准的"四舍五入",但负数情况下的"进一"是向绝对值增大的方向(例如 -1.5 舍入为 -1,因为 -1 > -1.5)。
3. 基本示例
javascript
Math.round(3.2); // 3
Math.round(3.5); // 4
Math.round(3.8); // 4
Math.round(-3.2); // -3
Math.round(-3.5); // -3 (关键:-3.5 舍入为 -3,因为 -3 大于 -3.5)
Math.round(-3.8); // -4
4. 特殊情况(边界值)
| 输入值 | 返回值 | 说明 |
|---|---|---|
Math.round(0) |
0 | 零 |
Math.round(0.49) |
0 | 小数部分 < 0.5 |
Math.round(0.5) |
1 | 小数部分 = 0.5,进位 |
Math.round(-0.5) |
-0 | 注意:返回 -0(但 -0 === 0 为 true) |
Math.round(1.5) |
2 | |
Math.round(-1.5) |
-1 | 见上规则 |
Math.round(Number.MAX_SAFE_INTEGER + 0.5) |
仍为安全整数范围,但注意精度丢失 | 超大数时需谨慎 |
Math.round(NaN) |
NaN | 非数字返回 NaN |
Math.round(Infinity) |
Infinity | |
Math.round(-Infinity) |
-Infinity |
5. Math.round 的底层行为(IEEE 754 影响)
Math.round 基于二进制浮点数运算,因此某些十进制小数无法精确表示时,舍入结果可能与预期不符。
javascript
Math.round(1.005 * 100) / 100; // 期望 1.01,实际 1.00
因为 1.005 在内存中实际为 1.0049999999999999,乘以 100 得 100.49999999999999,Math.round 后为 100,再除以 100 得 1.00。
解决方案(保留两位小数):
javascript
function preciseRound(num, decimals) {
const factor = Math.pow(10, decimals);
return Math.round((num + Number.EPSILON) * factor) / factor;
}
console.log(preciseRound(1.005, 2)); // 1.01
或者使用 toFixed 并转为数字(注意 toFixed 本身也有精度问题,但上述加 Number.EPSILON 技巧较常用)。
6. 与其他取整方法的对比
| 方法 | 规则 | 示例(对 -3.7, -3.2, 3.2, 3.7) |
|---|---|---|
Math.round |
四舍五入到最近的整数 | -4, -3, 3, 4 |
Math.floor |
向下取整(向负无穷) | -4, -4, 3, 3 |
Math.ceil |
向上取整(向正无穷) | -3, -3, 4, 4 |
Math.trunc |
直接去掉小数部分(向零取整) | -3, -3, 3, 3 |
图示比较(数值轴):
-4 -3 -2 0 2 3 4
|--------|--------|--------|--------|--------|--------|
-3.7 → floor = -4, trunc = -3, round = -4, ceil = -3
-3.2 → floor = -4, trunc = -3, round = -3, ceil = -3
3.2 → floor = 3, trunc = 3, round = 3, ceil = 4
3.7 → floor = 3, trunc = 3, round = 4, ceil = 4
7. 常见应用场景
7.1 保留 n 位小数(返回数字)
javascript
function roundTo(num, decimals) {
const factor = Math.pow(10, decimals);
return Math.round(num * factor) / factor;
}
roundTo(3.14159, 2); // 3.14
roundTo(1.005, 2); // 1 (精度问题,需加 EPSILON)
7.2 将任意数字映射到最近的整数(如评分四舍五入)
javascript
const score = 78.6;
const roundedScore = Math.round(score); // 79
7.3 模拟掷骰子(与 Math.random 配合,得到 1~6 均匀整数)
javascript
function rollDice() {
return Math.round(Math.random() * 5 + 1); // ❌ 错误写法,两端概率不均
}
// 正确写法:
function rollDiceCorrect() {
return Math.floor(Math.random() * 6) + 1;
}
警告 :
Math.round用于生成随机整数时会导致边界值概率减半,应使用Math.floor。
7.4 将百分比显示为整数
javascript
const percent = 0.8765;
console.log(Math.round(percent * 100) + '%'); // "88%"
8. 性能与注意事项
Math.round性能较高,是原生 C++ 实现的。- 对于需要严格十进制精度(如货币),避免直接使用
Math.round,推荐使用整数运算或decimal.js。 - 注意
-0的存在:Math.round(-0.5)返回-0,但-0在大多数比较和算术中与+0等价(-0 === 0为true),但Object.is(-0, 0)为false。序列化为 JSON 时-0变成0。
9. 模拟 Math.round 的简单实现(理解原理)
javascript
function myRound(x) {
const sign = x >= 0 ? 1 : -1;
const absX = Math.abs(x);
const fractional = absX - Math.floor(absX);
if (fractional < 0.5) {
return Math.floor(x);
} else {
return Math.ceil(x);
}
}
但实际引擎实现更加高效,直接使用原生的即可。
10. 总结
Math.round执行标准四舍五入 ,注意负数时-3.5舍入为-3。- 返回整数(
Number类型),对于浮点精度问题需额外处理。 - 与
Math.floor、Math.ceil、Math.trunc各有适用场景,理解区别才能正确选择。 - 不要用
Math.round配合Math.random生成随机整数(除非你清楚两端概率不均的后果)。
掌握 Math.round 及其陷阱,可以在数值处理中游刃有余。