最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript中的精度丟失與分?jǐn)偛黄絾栴}原因及解決方案

 更新時(shí)間:2026年03月12日 10:04:36   作者:yingjuxia.com  
這篇文章主要介紹了JavaScript中浮點(diǎn)數(shù)精度問題,包括根本原因、常見場(chǎng)景及解決方案,推薦使用整數(shù)運(yùn)算、BigInt或高精度庫(kù)(如decimal.js)來解決金額計(jì)算的精度問題,需要的朋友可以參考下

大家好!這是很多前端(尤其是金融、電商、支付、報(bào)表)開發(fā)者最頭疼的問題:

console.log(0.1 + 0.2);           // 0.30000000000000004
console.log(0.3 - 0.2);           // 0.09999999999999998
console.log(19.9 * 100);          // 1989.9999999999998
console.log(1.005.toFixed(2));    // "1.00" 而不是 "1.01"

更可怕的是分?jǐn)偛黄剑ń痤~拆分時(shí)總和對(duì)不上):

假設(shè) 100 元分給 3 個(gè)人,每人應(yīng)得 33.333… 元
toFixed(2) 后:33.33 + 33.33 + 33.33 = 99.99(差1分?。?/p>

今天這篇保姆級(jí)+生產(chǎn)級(jí)文章,一次性徹底講透原因 + 所有解決方案(從簡(jiǎn)單到企業(yè)級(jí)),看完你再也不會(huì)被精度坑了。

1. 根本原因:IEEE 754 雙精度浮點(diǎn)數(shù)(必懂?。?/h2>

JavaScript 的 Number 類型底層是 64位 IEEE 754 雙精度浮點(diǎn)數(shù)

  • 1位符號(hào) + 11位指數(shù) + 52位尾數(shù)(有效精度約15-16位十進(jìn)制)
  • 二進(jìn)制無法精確表示大部分十進(jìn)制小數(shù)(就像十進(jìn)制無法精確表示1/3)

經(jīng)典二進(jìn)制轉(zhuǎn)換演示(0.1 的二進(jìn)制是無限循環(huán)):

大整數(shù)精度丟失(超過 Number.MAX_SAFE_INTEGER = 9007199254740991):

console.log(9007199254740992 === 9007199254740993); // true!已丟失

2. 常見場(chǎng)景 & 問題匯總

場(chǎng)景典型表現(xiàn)后果
加減乘除小數(shù)0.1+0.2、0.3-0.2顯示多位小數(shù)或不相等
toFixed()1.005.toFixed(2) → “1.00”銀行級(jí)四舍五入錯(cuò)誤
大ID(雪花算法)JSON.parse后后幾位變0ID重復(fù)、數(shù)據(jù)錯(cuò)亂
金額分?jǐn)?/td>100 / 3 = 33.333… → toFixed后總和少1分分?jǐn)偛黄?/strong>(最致命)
循環(huán)累加0.1 加 10 次 ≠ 1報(bào)表總計(jì)對(duì)不上

3. 解決方案對(duì)比(2026推薦排序)

方案1:最簡(jiǎn)單——轉(zhuǎn)為整數(shù)計(jì)算(推薦日常金額)

轉(zhuǎn)為(或更小單位),全部用整數(shù)運(yùn)算,最后再除。

// 金額用分存儲(chǔ)
const price = 1999;  // 19.99元
const qty = 3;
const total = price * qty;           // 5997 分
console.log((total / 100).toFixed(2)); // "59.97" 完美

分?jǐn)偛黄浇K極解決(銀行家舍入 + 尾差調(diào)整):

function distribute(amount, parts) {
  const base = Math.floor(amount / parts);
  const remainder = amount % parts;
  const result = new Array(parts).fill(base);
  for (let i = 0; i < remainder; i++) result[i]++;
  return result.map(v => v / 100);  // 轉(zhuǎn)回元
}

distribute(10000, 3); // [3334, 3333, 3333] 分 → 總和正好100.00元

方案2:原生 BigInt(整數(shù)超大數(shù)專用,2026最推薦)

const a = 9007199254740992n;
const b = 1n;
console.log(a + b); // 9007199254740993n  精確!

金額場(chǎng)景(推薦結(jié)合方案1):

const priceInFen = 1999n;
const total = priceInFen * 3n; // 5997n
console.log(Number(total) / 100); // 59.97

方案3:高精度庫(kù)(金融/科學(xué)計(jì)算必備)

2026年主流庫(kù)對(duì)比(生產(chǎn)驗(yàn)證):

推薦優(yōu)先級(jí)

  1. decimal.js(最推薦)—— 任意精度、API最友好
  2. bignumber.js —— 輕量、速度快
  3. big.js —— 極簡(jiǎn)
  4. Dinero.js / currency.js —— 專門做貨幣

decimal.js 實(shí)戰(zhàn)代碼(復(fù)制即用):

import Decimal from 'decimal.js';
Decimal.set({ precision: 20, rounding: Decimal.ROUND_HALF_EVEN });
const a = new Decimal('0.1');
const b = new Decimal('0.2');
console.log(a.plus(b).toString());        // "0.3" 完美
const total = new Decimal('100');
const perPerson = total.dividedBy(3).toFixed(2); // "33.33"
console.log(perPerson); // 不會(huì)分?jǐn)偛黄?/pre>

toFixed 增強(qiáng)版(解決1.005問題):

function accurateToFixed(num, digits = 2) {
  return new Decimal(num).toFixed(digits);
}
accurateToFixed(1.005); // "1.01"

方案4:其他輔助技巧

  • JSON大數(shù):用 json-bigintBigInt 序列化
  • 比較時(shí)用 Number.EPSILONMath.abs(a - b) < Number.EPSILON
  • 顯示時(shí)永遠(yuǎn)用 .toFixed(2) + 庫(kù)

4. 生產(chǎn)最佳實(shí)踐(強(qiáng)烈建議)

  1. 所有金額后端存“分”或字符串,前端用 Decimal 或整數(shù)
  2. 前端計(jì)算全部走庫(kù),絕不用原生 + - * /
  3. 分?jǐn)倛?chǎng)景必須用整數(shù)分?jǐn)?+ 尾差調(diào)整算法
  4. 大ID一律用 BigInt 或字符串
  5. 測(cè)試:寫單元測(cè)試覆蓋 0.1+0.21.005.toFixed、100/3

5. 小結(jié) & 推薦工具

一句話記住

永遠(yuǎn)不要相信 JS 原生 Number 做精確計(jì)算,尤其是錢!

立即行動(dòng)

  • 金額類項(xiàng)目 → 安裝 decimal.js + 改成整數(shù)分存儲(chǔ)
  • 大數(shù)ID → 用 BigIntjson-bigint
  • 快速修復(fù) → 先用 toFixed(2) + Number.EPSILON 兜底

以上就是JavaScript中的精度丟失與分?jǐn)偛黄絾栴}原因及解決方案的詳細(xì)內(nèi)容,更多關(guān)于JavaScript精度丟失與分?jǐn)偛黄降馁Y料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

怀仁县| 都安| 滨州市| 青州市| 仲巴县| 年辖:市辖区| 樟树市| 若尔盖县| 漠河县| 平和县| 扶风县| 普安县| 莫力| 汨罗市| 丹巴县| 德惠市| 瓦房店市| 浏阳市| 乐山市| 霍林郭勒市| 武邑县| 滁州市| 武义县| 吉木乃县| 时尚| 内黄县| 隆回县| 彰化县| 蓝山县| 巴林左旗| 德州市| 武隆县| 丰原市| 泸溪县| 进贤县| 平和县| 锦州市| 西城区| 孝感市| 兰溪市| 峨边|