いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-349 (math/bigを使って丸め誤差が出ないように計算する)

関連記事

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

概要

以下、自分用のメモです。忘れない内にメモメモ。。。

以下の記事でとても勉強になりました。感謝。

math/bigというのがあるのですね。

engineering.mercari.com

自分の手で一度サンプル書いてみないと使い方とは理解できないので、以下にサンプルです。

サンプル

package floatop

import (
    "math/big"

    "github.com/devlights/gomy/output"
)

// RoundingError は、小数点計算において近似値が利用され丸め誤差が出るサンプルです。
//
// # REFERENCES
//   - https://engineering.mercari.com/blog/entry/20201203-basis-point/
func RoundingError() error {
    //
    // 0.01は2進数で正確に表現できないため、近似値が利用されて丸め誤差が生じる
    //
    var (
        v float64
    )

    for i := 0; i < 1000; i++ {
        v += 0.01
    }

    output.Stdoutl("[float64]", v) // 9.999999999999831

    //
    // math/big を利用して同様の処理を行う
    //
    var (
        v2 = new(big.Rat)
    )

    for i := 0; i < 1000; i++ {
        v2 = new(big.Rat).Add(v2, big.NewRat(1, 100))
    }

    output.Stdoutl("[big.Rat]", v2.FloatString(1)) // 10.0

    return nil
}

実行すると以下のようになります。

$ task
task: Task "build" is up to date
task: [run] ./try-golang -onetime

ENTER EXAMPLE NAME: floatop_rounding_error

[Name] "floatop_rounding_error"
[float64]            9.999999999999831
[big.Rat]            10.0


[Elapsed] 825.86µs

参考情報

big package - math/big - Go Packages

decimal --- 十進固定及び浮動小数点数の算術演算 — Python 3.12.0 ドキュメント

Goのおすすめ書籍

Go言語による並行処理

Go言語による並行処理

Amazon


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。