≪ Today I learned.
RSS購読
    公開日
    タグ
    JavaScript
    著者
    ダーシノ

    Math.sumPrecise()で数値配列の合計を取得する

    JavaScriptにおいて配列の数値の合計を求めるには、以下のようにArray#reduce()を使っていた。

    const nums = [1, 2, 3]
    const total = nums.reduce((total, n) => total + n, 0)
    
    console.log(total) // 6

    ただし、桁数の大きい数値や浮動小数点数を扱うと、計算の途中結果を格納する際に丸め処理によって精度の問題を引き起こすことがある。例えば、以下のようなケースだ。

    const nums = [0.1, 0.2, 0.3]
    const total = nums.reduce((total, n) => total + n, 0)
    
    console.log(total) // 0.6000000000000001

    この問題を解決するために、Math.sumPrecise()が使える。 Array#reduce()は便利な反面、何でもできてしまう(filter、map、forEachなど)ので、厄介なコードになりやすいため、個人的にはMath.sumPrecise()を推したい。

    const nums = [0.1, 0.2, 0.3]
    const total = Math.sumPrecise(nums)
    
    console.log(total) // 0.6
    function getPriceFrom(item: Item): number {
      // 商品のJANコードから価格を取得する処理
    }
    
    const cart: Item[] = [
      { jan: '1000000000001', name: '商品A' },
      { jan: '1000000000002', name: '商品B' },
      { jan: '1000000000003', name: '商品C' },
    ]
    
    const prices = cart.map(getPriceFrom)
    const total = Math.sumPrecise(prices)

    ただし、以下のような浮動小数点の精度の問題は完全には解決できない場合があるので注意が必要だ。

    const nums = [0.1, 0.2]
    const total = Math.sumPrecise(nums)
    
    console.log(total) // 0.30000000000000004