Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@Statham

GoとMongoDBとProtocol Buffersでの小数の扱い

More than 1 year has passed since last update.

MongoDB上でNumberDecimal()を使いdecimalで小数を格納していたのだが、それを"mongo-go-driver"を介してDecode()する時に、cannot decode 128-bit decimal into a float32 or float64 typeとエラーが出て困ったので、各々の小数周りの仕様を調べた。

それぞれの小数周りの仕様へのリンク集としても役立つはず。

Go

Go上で小数に対応する型は、Numeric typesの仕様によると、float32float64のよう。

Protocol Buffers

"proto3"のLanguage GuideにあるScalar Values Type表によると、proto上での小数表記はfloatdooubleで、それぞれGo上ではfloat => float32double => float64となるらしい。

MongoDB

MongoDB上では、schema定義のドキュメント曰く、doubledecimalが存在する。これはBson Typeにあたるので、Bsonの仕様書を見てみると、どうやら64bitで表現されるのがdoubleであり、128bitで表現されるのがdecimal (decimal128)であることがわかる。

MongoDBとGoの間でやり取りするには、基本的に"mongo-go-driver"を使うことになると思うが、その中の"go.mongodb.org/mongo-driver/bson"についての箇所を見ると、BSONのdoublefloat64に、128-bit decimalprimitive.Decimal128にエンコードされることがわかる。

"mongo-go-driver"でのDecimal128の扱いを読んでみると、BigInt()big.Intとexponential部分を返すメソッドはあるようだが、Decimal128をGo標準のfloat64などに変換するメソッドはないことがわかる。

結論 string 最強

今回は、計算したい要件がなく、ただMongoDBから取得したデータをGoを介してProtocol Buffer経由でクライアントに送りたいだけだったので、結局stringにすることにした。他にも、別にMongoDBに入れるのにdecimalであることにこだわりがなければ、doubleを使用することでGo上ではfloat64として扱うことができるので、問題は発生しない。

もし計算したいなら、Decimal128stringにして、それをさらにfloat64などにするのが良いのか、BigInt()を使って頑張れるのか("math/big"Floatに頑張って変換できれば良いのだが)、Decimal128のまま計算する方法があるのかはわかっていない。

何れにしても、小数周りはどの言語でも辛いんだなぁと思った。
(jsだけじゃなかった。。。

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Statham
JS (Jason Statham)が好きです。あとは、JS (JavaScript)とか、Solidityとか。ReactとTSは大好きです。最近はGoを少し触りましたが、その後 Rust に出会い、今は幸せです。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?