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

前端big.js解決大數(shù)字精度問題的使用教程和原理解析

 更新時間:2025年12月22日 09:35:00   作者:鵬多多  
big.js?作為輕量級的大數(shù)處理庫,以簡潔的?API?和清晰的源碼邏輯,成為解決精度丟失問題的主流選擇,本文將從?API?用法和源碼原理兩方面,全面解析?big.js?的核心價值

在前端開發(fā)中,處理金融、電商等領(lǐng)域的數(shù)字計算時,JavaScript 原生的 Number 類型因采用 64 位雙精度浮點數(shù)存儲,極易出現(xiàn)精度丟失問題(如 0.1 + 0.2 !== 0.3)。big.js 作為輕量級的大數(shù)處理庫,以簡潔的 API 和清晰的源碼邏輯,成為解決該問題的主流選擇。本文將從 API 用法和源碼原理兩方面,全面解析 big.js 的核心價值。

1. 核心特性

big.js 專為高精度十進制計算設(shè)計,核心特點:

  • 輕量(僅 ~6KB 無依賴);
  • 不可變設(shè)計(所有操作返回新實例);
  • 可配置精度、舍入模式;
  • 兼容所有主流瀏覽器和 Node.js。

2. 常用和特殊API詳解

2.1. 基礎(chǔ)初始化 API

big.js 的核心是 Big 構(gòu)造函數(shù),用于創(chuàng)建大數(shù)實例,支持多種入?yún)㈩愋停?/p>

import Big from 'big.js';

// 1. 基礎(chǔ)初始化(支持數(shù)字、字符串、Big 實例)
const num1 = new Big(123); // 數(shù)字
const num2 = new Big('123.4567890123456789'); // 字符串(推薦,避免精度丟失)
const num3 = new Big(num2); // 基于已有 Big 實例創(chuàng)建

// 2. 特殊值初始化
const zero = new Big(0); // 0
const negative = new Big('-987654321.987654321'); // 負數(shù)
const scientific = new Big('1.23e+5'); // 科學計數(shù)法

注意:初始化時優(yōu)先使用字符串入?yún)?/strong>,避免數(shù)字本身已因浮點數(shù)存儲丟失精度。

2.2. 常用計算 API

big.js 提供了完整的算術(shù)運算方法,所有方法均返回新的 Big 實例(原實例不變):

API 方法作用示例
plus(n)加法new Big(0.1).plus(0.2).toString() → "0.3"
minus(n)減法new Big(1).minus(0.9).toString() → "0.1"
times(n)乘法new Big(2).times(0.1).toString() → "0.2"
div(n)除法new Big(1).div(3).toString() → "0.3333333333"
mod(n)取模new Big(5).mod(2).toString() → "1"
pow(n)冪運算new Big(10).pow(3).toString() → "1000"

示例代碼:

// 高精度加法
const a = new Big('0.1');
const b = new Big('0.2');
const sum = a.plus(b);
console.log(sum.toString()); // "0.3"

// 高精度除法(默認精度 10 位)
const c = new Big('1');
const d = new Big('3');
const div = c.div(d);
console.log(div.toString()); // "0.3333333333"

2.3. 特殊配置 & 工具 API

2.3.1. 全局配置 API

big.js 支持全局配置精度和舍入模式,核心配置項:

// 1. 設(shè)置全局精度(小數(shù)點后位數(shù)),默認 20
Big.DP = 15; 

// 2. 設(shè)置舍入模式,默認 ROUND_HALF_UP(四舍五入)
Big.RM = Big.roundHalfUp; 

// 舍入模式枚舉(常用):
// Big.roundUp: 向上取整
// Big.roundDown: 向下取整
// Big.roundHalfEven: 銀行家舍入(四舍六入五取偶)

2.3.2. 實例工具 API

API 方法作用示例
toString()轉(zhuǎn)為字符串new Big(123.45).toString() → "123.45"
toFixed(dp)固定小數(shù)位數(shù)new Big(1.234).toFixed(2) → "1.23"
toPrecision(pre)固定有效數(shù)字new Big(123.45).toPrecision(3) → "123"
cmp(n)比較大小(-1/0/1)new Big(5).cmp(3) → 1
abs()絕對值new Big(-123).abs() → Big { s: 1, e: 2, c: [1,2,3] }
neg()取反new Big(123).neg() → Big { s: -1, e: 2, c: [1,2,3] }
isZero()判斷是否為 0new Big(0).isZero() → true
isNegative()判斷是否為負數(shù)new Big(-1).isNegative() → true

示例代碼:

// 配置精度和舍入模式
Big.DP = 2;
Big.RM = Big.roundUp;

// 向上取整的除法
const num = new Big('1').div('3');
console.log(num.toString()); // "0.34"

// 比較大小
const x = new Big(10);
const y = new Big(5);
console.log(x.cmp(y)); // 1(x > y)
console.log(x.cmp(x)); // 0(相等)
console.log(y.cmp(x)); // -1(y < x)

3. 源碼解析

big.js 解決精度問題的核心思路是:將數(shù)字轉(zhuǎn)為字符串拆分存儲,通過模擬手工計算的方式實現(xiàn)算術(shù)運算,而非依賴 JavaScript 原生的浮點數(shù)運算。

3.1. 核心數(shù)據(jù)結(jié)構(gòu)

Big 實例的內(nèi)部存儲結(jié)構(gòu)(核心屬性):

// 以 new Big('123.456') 為例
{
  s: 1,        // 符號位:1 正數(shù),-1 負數(shù)
  e: 2,        // 指數(shù):小數(shù)點偏移量(整數(shù)部分的位數(shù) - 1),123.456 的整數(shù)部分是 123(3 位),故 e = 3-1 = 2
  c: [1,2,3,4,5,6] // 系數(shù)數(shù)組:存儲數(shù)字的每一位(無小數(shù)點,通過 e 定位)
}
  • 符號位 s:分離正負,避免運算時處理符號干擾;
  • 指數(shù) e:記錄小數(shù)點位置,將小數(shù)轉(zhuǎn)為“整數(shù) + 指數(shù)”的形式;
  • 系數(shù)數(shù)組 c:以數(shù)組存儲每一位數(shù)字,徹底規(guī)避浮點數(shù)的二進制存儲精度丟失。

3.2. 核心原理:從“二進制浮點”到“十進制手工計算”

JavaScript 原生精度丟失的根源是:十進制小數(shù)無法被二進制浮點數(shù)精確表示(如 0.1 的二進制是無限循環(huán)小數(shù))。big.js 則回歸“手工計算邏輯”,步驟如下:

步驟 1:初始化時的字符串解析

當傳入數(shù)字/字符串時,big.js 會先將其轉(zhuǎn)為字符串,逐字符解析為 s/e/c

// 源碼核心解析邏輯(簡化版)
function parse(str) {
  let s = 1;
  let e = 0;
  let c = [];

  // 1. 處理符號
  if (str[0] === '-') {
    s = -1;
    str = str.slice(1);
  }

  // 2. 處理小數(shù)點
  const dotIndex = str.indexOf('.');
  if (dotIndex !== -1) {
    e = dotIndex - (str.length - 1); // 計算指數(shù)偏移
    str = str.replace('.', ''); // 移除小數(shù)點
  }

  // 3. 解析每一位到系數(shù)數(shù)組
  for (let i = 0; i < str.length; i++) {
    c.push(Number(str[i]));
  }

  // 4. 去除前導零、調(diào)整指數(shù)
  // ...(源碼中會處理前導零、末尾零等邊界情況)

  return { s, e, c };
}

步驟 2:算術(shù)運算的“手工模擬”

以加法為例,big.js 模擬人類手工加法的“對齊小數(shù)點 → 逐位相加 → 處理進位”邏輯:

// 加法核心邏輯(簡化版)
function add(a, b) {
  // 1. 對齊小數(shù)點(統(tǒng)一指數(shù) e)
  let [x, y] = alignExponent(a, b); // 對齊后,x.e === y.e

  // 2. 逐位相加(從后往前)
  let carry = 0;
  const c = [];
  for (let i = x.c.length - 1; i >= 0; i--) {
    const sum = x.c[i] + y.c[i] + carry;
    c.unshift(sum % 10); // 當前位
    carry = Math.floor(sum / 10); // 進位
  }

  // 3. 處理最后一位進位
  if (carry) c.unshift(carry);

  // 4. 構(gòu)建新的 Big 實例
  return new Big({ s: a.s, e: x.e, c });
}

// 對齊指數(shù)的輔助函數(shù)
function alignExponent(a, b) {
  const diff = a.e - b.e;
  if (diff > 0) {
    // a 的指數(shù)更大,給 b 的系數(shù)數(shù)組補零(相當于小數(shù)點右移)
    b.c = b.c.concat(Array(diff).fill(0));
    b.e = a.e;
  } else if (diff < 0) {
    // b 的指數(shù)更大,給 a 的系數(shù)數(shù)組補零
    a.c = a.c.concat(Array(-diff).fill(0));
    a.e = b.e;
  }
  return [a, b];
}

乘法、除法等運算的核心邏輯同理:

  • 乘法:模擬“逐位相乘 → 錯位相加 → 處理進位”;
  • 除法:模擬“試商 → 求余 → 補零繼續(xù)除”,直到達到配置的精度(DP);
  • 所有運算均基于十進制數(shù)字數(shù)組,而非二進制浮點數(shù),從根源避免精度丟失。

步驟 3:舍入邏輯的精準控制

big.js 提供多種舍入模式,核心是通過判斷“舍棄位的數(shù)字”決定是否進位,例如四舍五入(ROUND_HALF_UP):

// 舍入核心邏輯(簡化版)
function round(c, dp, rm) {
  const cutIndex = dp; // 保留位數(shù)的索引
  const discard = c[cutIndex]; // 舍棄位的數(shù)字

  if (rm === Big.roundHalfUp) {
    // 四舍五入:舍棄位 >=5 則進位
    if (discard >= 5) {
      carry(c, cutIndex - 1); // 向前一位進位
    }
    c.splice(cutIndex); // 截斷舍棄位
  }
  return c;
}

3.3. 源碼核心亮點

  • 不可變設(shè)計:所有運算返回新實例,原實例不修改,避免副作用;
  • 最小化計算:僅處理必要的數(shù)字位,去除前導零、末尾零,提升性能;
  • 可配置化:通過 DP(精度)、RM(舍入模式)適配不同業(yè)務場景;
  • 輕量無依賴:核心代碼僅千行左右,無外部依賴,易于集成。

4. 適用場景 & 注意事項

適用場景

  • 金融計算(金額、稅率、利息);
  • 電商價格計算(優(yōu)惠券、折扣、滿減);
  • 高精度數(shù)據(jù)展示(科學計算、統(tǒng)計報表)。

注意事項

  • 初始化優(yōu)先使用字符串,避免數(shù)字入?yún)⑻崆皝G失精度;
  • 避免頻繁創(chuàng)建 Big 實例,可復用實例提升性能;
  • 與原生 Number 互轉(zhuǎn)時,需通過 toString()toNumber() 方法,避免直接強制轉(zhuǎn)換;
  • big.js 僅處理十進制大數(shù),如需處理大整數(shù)(如 ID、雪花算法),可選擇 bigintbn.js。

5. 總結(jié)

big.js 作為前端大數(shù)精度處理的經(jīng)典庫,核心價值在于:

  • 字符串解析 + 十進制數(shù)組存儲的方式,規(guī)避了 JavaScript 浮點數(shù)的二進制存儲缺陷;
  • 通過模擬手工計算的算術(shù)邏輯,實現(xiàn)高精度的加減乘除等運算;
  • 提供簡潔的 API 和可配置項,適配不同業(yè)務場景的精度需求。

在處理前端數(shù)字精度問題時,big.js 以輕量、易用、可靠的特性,成為開發(fā)者的首選方案。理解其 API 用法和源碼原理,不僅能解決實際業(yè)務問題,也能深入理解 JavaScript 數(shù)字存儲的底層邏輯。

以上就是前端big.js解決大數(shù)字精度問題的使用教程和原理解析的詳細內(nèi)容,更多關(guān)于big.js使用教學的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 網(wǎng)站基于flash實現(xiàn)的Banner圖切換效果代碼

    網(wǎng)站基于flash實現(xiàn)的Banner圖切換效果代碼

    這篇文章主要介紹了網(wǎng)站基于flash實現(xiàn)的Banner圖切換效果代碼,是基于Flash與js實現(xiàn)的banner圖片自動定時切換特效,并附有完整的示例源碼,非常具有實用價值,需要的朋友可以參考下
    2014-10-10
  • 使用typescript類型實現(xiàn)ThreeSum

    使用typescript類型實現(xiàn)ThreeSum

    這篇文章主要介紹了使用typescript類型實現(xiàn)ThreeSum,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以一下,希望對你學習又是幫助
    2022-08-08
  • 基于JavaScript實現(xiàn)線性漸變的高斯模糊效果

    基于JavaScript實現(xiàn)線性漸變的高斯模糊效果

    這篇文章主要為大家詳細介紹了高斯模糊算法以及線性漸變的高斯模糊算法的原理,并通過一個小demo展示了如何實現(xiàn)y方向上線性漸變的高斯模糊效果,需要的可以了解下
    2024-01-01
  • Javascript仿PHP $_GET獲取URL中的參數(shù)

    Javascript仿PHP $_GET獲取URL中的參數(shù)

    這篇文章主要介紹了Javascript仿PHP $_GET獲取URL中的參數(shù)代碼實例,需要的朋友可以參考下
    2014-05-05
  • axios取消請求、配置的操作方法

    axios取消請求、配置的操作方法

    Axios 是一個基于 Promise 的 HTTP 客戶端,用于瀏覽器和 Node.js,在實際開發(fā)中,有時候需要取消已經(jīng)發(fā)起的請求,同時也需要對請求進行各種配置,以下分別介紹 Axios 取消請求和配置請求的方法,感興趣的朋友一起看看吧
    2025-02-02
  • JS如何將秒數(shù)轉(zhuǎn)化為時分秒的形式

    JS如何將秒數(shù)轉(zhuǎn)化為時分秒的形式

    在實際工作中經(jīng)常會遇見把秒數(shù)轉(zhuǎn)化為時分秒的問題,如何處理呢?下面這篇文章主要給大家介紹了關(guān)于JS如何將秒數(shù)轉(zhuǎn)化為時分秒形式的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-12-12
  • umi4.js基本使用方法示例詳解

    umi4.js基本使用方法示例詳解

    Umi4已于今年6月份發(fā)布,同時支持?Vite?和?Webpack?兩種構(gòu)建方式,對詬病已久的mufs做了優(yōu)化,另外還支持vue,這篇文章主要介紹了umi4.js基本使用方法的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-09-09
  • 基于JS遞歸函數(shù)細化認識及實用實例(推薦)

    基于JS遞歸函數(shù)細化認識及實用實例(推薦)

    下面小編就為大家?guī)硪黄贘S遞歸函數(shù)細化認識及實用實例(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • 使用swiper自定義分頁點擊跳轉(zhuǎn)指定頁面

    使用swiper自定義分頁點擊跳轉(zhuǎn)指定頁面

    這篇文章主要介紹了使用swiper自定義分頁點擊跳轉(zhuǎn)指定頁面方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • javascript之Object.assign()的痛點分析

    javascript之Object.assign()的痛點分析

    這篇文章主要介紹了javascript之Object.assign()的痛點分析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03

最新評論

晋城| 汨罗市| 大邑县| 峨眉山市| 应城市| 滁州市| 特克斯县| 崇明县| 古交市| 河南省| 桃园县| 凤山县| 囊谦县| 台安县| 安泽县| 突泉县| 梁河县| 富宁县| 罗定市| 湖口县| 宁城县| 镇原县| 定安县| 祁门县| 腾冲县| 湘阴县| 岳普湖县| 许昌县| 汶上县| 米脂县| 峨眉山市| 买车| 遵义县| 博野县| 澄迈县| 和硕县| 衡阳市| 定州市| 巫溪县| 瑞安市| 酒泉市|