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

JavaのBigDecimalをtoStringしたときに指数表記(E)が出ないようにする

More than 1 year has passed since last update.

環境

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}
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