在 JavaScript 中实现保留两位小数的实用方法

一、前言

在前端开发中,保留两位小数 是非常常见的需求(比如金额、利率、百分比等)。看似简单,但 JS 的浮点数精度问题会带来一些坑。本篇汇总几种常用做法、优缺点和推荐场景,帮你快速选对方案。


二、常见方法与示例

1. 最简单:toFixed(2)(用于展示)

  • 返回字符串(用于 UI 展示最方便)。
  • 直接四舍五入,语法最简洁。
let n = 3.14159;
console.log(n.toFixed(2)); // "3.14"
console.log((3.1).toFixed(2)); // "3.10"

注意toFixed 返回的是字符串,且会受到浮点精度影响:

console.log((1.005).toFixed(2)); // "1.00"(很多人期望 "1.01")

2. 推荐用于计算:基于放大 + 四舍五入(加 Number.EPSILON 修正)

  • 适合需要数值类型的场景(参与后续计算)。
  • Number.EPSILON 修复常见的浮点误差。
function roundToTwo(num) {
  return Math.round((num + Number.EPSILON) * 100) / 100;
}

console.log(roundToTwo(3.14159)); // 3.14
console.log(roundToTwo(1.005));   // 1.01

原理:先乘以 100 放大,四舍五入,最后除回去。Number.EPSILON 用于抵消二进制表示引入的微小误差。


3. 用于展示并支持国际化:Intl.NumberFormat

  • 适合格式化输出(含千分位、货币符号等)。
  • 可控制最小/最大小数位。
const fmt = new Intl.NumberFormat('zh-CN', {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

console.log(fmt.format(3.1));     // "3.10"
console.log(fmt.format(12345.678)); // "12,345.68"

4. 截断(不四舍五入):直接截断两位小数

  • 业务上有时需要 不进位(如某些财务规则)。
function truncateTwo(num) {
  return Math.trunc(num * 100) / 100;
  // 或者 Math.floor(num * 100) / 100 (对负数行为不同)
}

console.log(truncateTwo(3.149)); // 3.14
console.log(truncateTwo(3.999)); // 3.99

5. 金额推荐做法:以“分”为单位(整数)计算

  • 对于金钱计算,推荐把金额 *100 后作为整数处理,避免浮点累积误差,最后再格式化展示。
// 存储和计算都用整数 cents
let priceCents = Math.round(19.99 * 100); // 1999
let qty = 3;
let totalCents = priceCents * qty; // 5997
let total = totalCents / 100; // 59.97

6. 使用高精度库(需要极高精度或复杂业务)

  • 推荐库:decimal.jsbig.jsbignumber.js 等。
  • 适合金融级别精度或需要精确的小数运算场景。

示例(伪代码,需安装库):

// 使用 decimal.js(需 npm install decimal.js)
const Decimal = require('decimal.js');
let a = new Decimal(1.005);
console.log(a.toFixed(2)); // "1.01"






次阅读

扫描下方二维码,关注公众号:程序进阶之路,实时获取更多优质文章推送。


扫码关注

评论