[JS] 浮點數精度問題


Posted by mike-hsieh on 2024-03-13

使用JS計算時,通常都會遇到浮點數的精度問題,例如以下:

// 使用js浮點數相加:
// 0.1 + 0.2 = 0.30000000000000004
// 0.33 * 10 = 3.3000000000000003


解決的方法:

// 解法:
parseFloat((0.1 + 0.2).toPrecision(12)) -- result: 0.3
parseFloat((0.33 * 10).toPrecision(12)) -- result: 3.3

// 可以封裝成方法
function strip(num, precision = 12) {
  return +parseFloat(num.toPrecision(precision));
}

那為什麼要 toPrecision(12) 呢?
目的是要取精度,如果把精度提高,這樣又會現出原形了,所以12是個常見的經驗值,可以依照現況調整。

// 精度提高結果
parseFloat((0.1 + 0.2).toPrecision(18)) -- result: 0.30000000000000004
parseFloat((0.33 * 10).toPrecision(18)) -- result: 3.3000000000000003


實際背後的原因

就是 JavaScript 中所有數位包括整數和小數都只有一種類型 — Number。 它的實現遵循 IEEE 754 標準,使用 64 位固定長度來表示,也就是標準的 double 雙精度浮點數(相關的還有 float 32 位單精度)。:

// 0.1 和 0.2 都轉化成二進位後再進行運算
0.0001100110011001100110011001100110011001100110011001101 +
0.001100110011001100110011001100110011001100110011001101 =
0.0100110011001100110011001100110011001100110011001100111

// 轉成十進位正好是0.300000000000000004




詳細說明可以詳閱: https://tie.pub/2020/11/js-float-number/


#Double-precision floating-point format #浮點數 #精度問題







Related Posts

[Power BI] Data Cleansing #1

[Power BI] Data Cleansing #1

[04] JavaScript 入門 - 強制轉型、Truthy & Falsy、條件式

[04] JavaScript 入門 - 強制轉型、Truthy & Falsy、條件式

3. Migrations

3. Migrations


Comments