Goでdecimalを扱う方法|floatとの違い・誤差問題・ライブラリ比較

はじめに

Goにはdecimal型は存在せず、用途に応じて外部ライブラリを選択する必要があります。

  • decimal型に関する誤解
  • decimal型とfloat型の違い
  • decimalのライブラリ

の順序で解説します。

decimal型に関する誤解

Go言語のdecimalは固定小数点型と解釈されることが多いですが、厳密な意味では不正確です。

正確にはdecimalは、Goの組み込み型ではなく、概念です。外部
ライブラリごとに以下のような実装方式が存在します。

  • 固定小数点(例:整数+スケール)
  • 10進浮動小数点(任意精度)

decimal型とfloat型の違い

簡潔にまとめると、以下の通りです。

  • decimal型 : 値の精度は高いが処理が遅い。
  • float型 : 高速だが誤差が生じる可能性がある。

decimal型の概要

  • 固定小数点(例:整数+スケール)と10進浮動小数点(任意精度)の2種類が存在します。
  • Goの組み込み型に decimal 型は存在しません。
    • 組み込み型で高精度な数値計算を行う場合は、math/big パッケージ(big.Int / big.Rat / big.Float)を利用するか、 外部の decimal ライブラリを使用する必要がある。

特徴

2進浮動小数点よりも人間の期待に近い形で10進数を扱えます。
ただし、精度・丸め・スケールに依存し、常に誤差がないわけではありません。

a, _ := decimal.NewFromString("0.1")
b, _ := decimal.NewFromString("0.2")
fmt.Println(a.Add(b))

結果:0.3
→ 10進数としては意図通りに表現できる。

また、ライブラリによっては、整数部・小数部ともに桁数を任意に決められます。

問題

  • 処理速度が遅い(計算コストが高い)。
  • メモリの消費量が多い。
  • Goの標準型ではない。

向いている用途

  • 金融計算や通貨・税計算
  • 高精度な数値計算

代表的な外部のdecimalライブラリ

  1. shopspring/decimal
  2. cockroachdb/apd
  3. ericlagergren/decimal
  4. govalues/decimal

float型の概要

Go言語のfloat型は、2進浮動小数点であり、Goの標準ライブラリとして以下の2種類が存在します。

  • float32 : 32bit(単精度)
  • float64 : 64bit(倍精度)

特徴

  • 32bit / 64bit 固定です。
  • ハードウェアで高速処理されます。

問題

処理結果に誤差が生じる可能性があります。

fmt.Println(0.1 + 0.2)

結果:0.30000000000000004
→ 誤差が発生

小数が2進数で正確に表現できない(例えば、0.1は2進数では有限表現できない)ため、近似値で計算されます。

向いている用途

  • 科学計算
  • グラフィックス
  • 誤差が許容される処理

decimal型とfloat型の違いまとめ

観点decimal型float型
精度多くの10進数を意図した通りの精度で扱える誤差が生じる可能性がある
処理速度遅い速い
サイズ任意精度のため可変ビット幅固定
用途金額・厳密値計算・近似値
DB(DECIMAL)との相性互換性が高い(DECIMAL型への変換がよく実施される)ズレが生じる可能性がある(float64とFLOAT/DOUBLEの変換がよく実施される)

Goのdecimalライブラリ比較

代表的には以下です。
現時点での実務候補は shopspring/decimal か cockroachdb/apd が中心です。

ライブラリ特徴向いている用途
shopspring/decimalAPIが簡単で利用実績が多い。金額、DBの DECIMAL、一般的な業務アプリ。
cockroachdb/apdGeneral Decimal Arithmetic準拠寄り。高精度計算、DB内部実装寄り、厳密な丸め制御。
ericlagergren/decimal高性能な任意精度decimal。高性能な数値計算や低レイヤ用途で使われることがある。
govalues/decimal金融トランザクション向け、正しく丸める設計。金融系、immutable重視、比較的新しい設計。

なお、decimalライブラリは以下の2系統に分類されます。

  • 固定小数点(スケール付き整数型)
    • shopspring/decimal
    • govalues/decimal
  • 10進浮動小数点(任意精度)
    • cockroachdb/apd
    • ericlagergren/decimal

shopspring/decimal

https://github.com/shopspring/decimal

メリット

  • Goのdecimalライブラリとして利用実績が多い
  • APIが分かりやすい
  • database/sql やJSONとの相性も比較的よい
  • 内部的には整数+スケールで管理されるため、MySQL DECIMAL と考え方が近い

GitHub上でも “arbitrary-precision fixed-point decimal numbers in Go” と説明されています。最新リリースは v1.4.0 です。(GitHub)

デメリット

  • 高頻度計算では遅くなりやすい
  • 不変(immutable)であるため、演算ごとに値を作る設計
  • 厳密な数値仕様・丸め制御を細かくやる用途では cockroachdb/apd の方が向く場合がある

安全性・信頼性

業務アプリでは第一候補にしてよいです。
金額・税率・DBの DECIMAL を扱う用途なら、最も無難です。


cockroachdb/apd

https://github.com/cockroachdb/apd

メリット

  • General Decimal Arithmetic仕様をかなり意識した設計
  • 丸め・精度・条件フラグを細かく制御できる
  • “panic-free operation” を特徴として明示している
  • CockroachDB由来で、信頼性重視の設計

Go Packagesでも、Pythonの decimal やGCC decimal extensionと同じGeneral Decimal Arithmetic仕様を多く実装し、panic-free operationを特徴に挙げています。(Go Packages)

デメリット

  • APIがやや重い
  • Context を理解する必要がある
  • 単純な金額計算だけなら過剰

安全性・信頼性

精度制御・丸め規則・高信頼計算が必要なら最有力です。
ただし、通常のCRUD中心の業務アプリでは少し複雑です。


ericlagergren/decimal

https://github.com/ericlagergren/decimal

メリット

  • 高性能な任意精度decimal
  • General Decimal Arithmetic寄り
  • SQLBoilerの types.Decimal 周辺で登場することがある

GitHubでは “high-performance, arbitrary-precision, floating-point decimal library”(10進ベースの浮動小数点)と説明されています。(GitHub)

デメリット

  • 最終リリースが古めで、v3.3.1 は 2019年リリース(GitHub)
  • SQLBoilerと組み合わせた際に cannot convert type: types.Decimal 系の問題報告がある(GitHub)
  • 一般用途では shopspring/decimal や cockroachdb/apd より選定理由を説明しにくい

安全性・信頼性

SQLBoilerが生成する型との互換性都合で使うなら候補になりえます。
ただし、新規にdecimalライブラリを選ぶなら、まず shopspring/decimal または cockroachdb/apd を検討する方が無難だと思われます。


govalues/decimal

https://github.com/govalues/decimal

メリット

  • 金融トランザクション向けを明示
  • 正しく丸めるdecimalを提供
  • JSON / XML / SQL / BSON 連携を意識
  • heap allocation削減を特徴にしている

READMEでは、transactional financial systems向け、correctly rounded decimals、SQL/JSON/XML/BSON対応、多くのケースでヒープ割り当てを回避する設計、を特徴として挙げています。(GitHub)

デメリット

  • shopspring/decimal より利用実績は少なめ
  • 比較的新しい
  • チーム内で知見が少ない可能性がある

安全性・信頼性

設計思想はかなり良いです。
ただし、業務で採用するなら、利用実績・依存リスク・チーム習熟度を確認した方がよいです。


2026年5月時点での方針

通常の業務アプリ / MySQL DECIMAL

shopspring/decimal

理由:

  • 使いやすい
  • 利用実績が多い
  • MySQL DECIMAL との相性が良い(スケール付き整数として扱うため、概念的に近い)
  • チームに説明しやすい

厳密な丸め・高精度計算が必要

cockroachdb/apd

理由:

  • 精度・丸め・エラー条件の制御が強い
  • 数値処理として堅い

書籍紹介

今でも時折読み返しています。個人的には名著の部類だと思います。

AIがプログラミングをしてくれる局面が増えたとはいえ、そのソースコードに責任を持つのはエンジニアです。

是非、プログラミングに携わる方には一度読んでいただきたいです!

前々から気になっている書籍でしたが、改訂版が出たようです。

目次を見るだけでワクワクしますね!

本記事は以上です。

タイトルとURLをコピーしました