Help us understand the problem. What is going on with this article?

GsonでJavaScriptが64bit整数を扱えない問題を回避する方法

More than 3 years have passed since last update.

発生した問題

JavaScriptでは64bitの整数を扱うことができない。
32bitの範囲を超えた数値は64bitの浮動小数点型に変換されるが、整数として精度を保てるのは53bitまでとなる。
このため整数として53bitを超える精度が必要な場合には何らかの対処が必要となる。

kotlinでGsonを使ってWeb-APIを作成していた際に、この問題に突き当たった。
DBレコードのIDを64bit整数として設計していたためだ。

解決方法

val gson = GsonBuilder().setLongSerializationPolicy(LongSerializationPolicy.SRING)

以下古い情報(コメントで指摘をいただき、実は簡単に設定できました。)

Gsonには型ごとにどのようにJSONとして書くか、または読み取るかを設定する機能がある。
この機能を使い、Long型は無条件で文字列に変換して返すことでこの問題を回避した。
クライアント側で64bit整数に対する計算が発生する場合はこれだけでは済まないが今回は計算は不要であった。

Long型を文字列型に変換できるように設定する例

private val gson = with(GsonBuilder()) {
    registerTypeAdapter(Long::class.javaObjectType, object: TypeAdapter<Long>() {
        override fun write(out: JsonWriter?, value: Long?) {
            out ?: throw IllegalStateException()
            out.value(value?.toString() ?: "")
        }

        override fun read(r: JsonReader?): Long? {
            r ?: throw IllegalStateException()
            return r.nextLong()
        }
    })
    create()
}

write()関数を改造すれば、53bitの精度に収まる範囲であれば整数型のまま返すことや、逆に53bitを超える場合はエラーにするいったことも可能だ。

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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした