floatは有効桁数が7桁なのでそれ以上の有効桁数を持つdoubleに変換すると誤差が出る。
float fl = 20.6f;
system.out.println(fl); // 20.6
system.out.println((double) fl); // 20.600000381469727
プリミティブ型だしなんかしら用意された解決方法があんだろうと思い探してみた。
解決案1 Float.doubleValue()
を使う
float fl = 20.6f;
system.out.println(fl); // 20.6
system.out.println(((Float) fl).doubleValue()); // 20.600000381469727
このメソッド必要ある?
解決案2 一度BigDecimalに変換する
float fl = 20.6f;
system.out.println(fl); // 20.6
system.out.println(new BigDecimal(fl).doubleValue()); // 20.600000381469727
後で確認したらBigDecimalに変換した時点で誤差ってた。
float型を受け取るコンストラクタが無いんだから当たり前でした。
解決案3 一度Stringに変換する
float fl = 20.6f;
system.out.println(fl); // 20.6
system.out.println(Double.parseDouble(((Float) fl).toString())); // 20.6
できました。
floatの値が大きくなって指数表記になってもちゃんとparseしてくれる。
でもなんか負けた気がする。
他には有効桁数が7桁なんだから8桁目を四捨五入するのもありなのかな。
めんどくさくなりそうなので試してないです。
ネットを探してもなかなかこれについて触れているところがない。まあ普通最初からdoubleかBigDecimal使うしなぁ。
今回は外注先が作ったコードでfloatをdoubleにキャストしているところがあって、直させるために調べたんだけどその解決案が文字列に変換ってなんかかっこ悪いなあ。