LoginSignup
5
8

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-02-06

発生した問題

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を超える場合はエラーにするいったことも可能だ。

5
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
8