環境
Java 8
SpringBoot 1.5.10
Jackson Core 2.8.10
現象
BigDecimal型を使っているときにtoString
を呼ぶと指数表記(E)が出現することがあります。
手元の環境で試してみたところ、0.1からはじめて0.000001(10のマイナス6乗)まではそのままの形ですが、0.0000001(10のマイナス7乗)からは指数表記(E)が出現しました。
BigDecimal fieldA = new BigDecimal("0.000001"); // .toString()したら 0.000001
BigDecimal fieldB = new BigDecimal("0.0000001"); // .toString()したら 1E-7
指数表記(E)が出現する基準についてはBigDecimal.toStringのドキュメントに詳しく書いてありますので、そちらを参照してください。
対応
toStringのかわりにtoPlainStringを使えばいくつであってもそのままの形で吐いてくれます。
BigDecimal fieldA = new BigDecimal("0.0000001");
System.out.println(fieldA.toString()); // -> 1E-7
System.out.println(fieldA.toPlainString()); // -> 0.0000001
Jacksonを使っているときにtoPlainStringしてほしい
Jacksonを使ってJavaのオブジェクトをJSONに変換している場合、デフォルトの挙動では、toStringが呼ばれるため、数によっては指数表記(E)が登場してしまいます。
これを防ぐために、内部でtoString
の代わりにtoPlainString
が呼ばれるようにするWRITE_BIGDECIMAL_AS_PLAINという設定があります。(Jacksonの2.3から)
Spring Bootの場合は、application.yml
に下記の設定を書けばokです。
spring:
jackson:
generator:
write_bigdecimal_as_plain: true
余談
jqを使っていると指数を使う形式に変換されるので注意です。
動作確認時に、ターミナルからcurlしてjqでフォーマットして確認していたので、少しハマりました。
# jq使うとeが出現する
$ curl localhost:8081 | jq
{
"fieldA": 1e-53,
"fieldB": 9e-15
}
# jq使わないとeが出現しない
$ curl localhost:8081
{"fieldA":0.000001,"fieldB":0.0000001}