2進数と10進数の狭間
久々に見ました。意図したように 10 進表記されない例。
118.175 という数値を倍精度浮動小数点に格納して、これを小数点以下 2 桁で表示しようとすると、118.17 になります。
発端は PostgreSQL の TO_CHAR でフォーマットを指定したときの挙動が、上記のようになったのが発見されたのに続き、同じことを perl で printf、C で printf を同じ現象。多分、どれも同じロジック。
確かにこの値、2 進数だと循環小数になってしまう微妙な値。これを小数点以下2桁とう条件にかけると、118.17 のほうに近い、という判断になるんだろうなぁ。循環小数ということは、ある精度以下は切り捨てられた数値として入っているわけで、それを使って 10 進表記を求めようとすると、下側の値のほうがより近い、となる。
...というのは全くの想像なので、読んでる人は鵜呑みにしないように(^^;。
で、回避方は、元々 double precision の値のフィールドを numeric でキャストして ROUND を使う。
ROUND(CAST(data as numeric), 2)
といった具合。これで、「人間が意図した数字」になった。
実は Excel で書式を指定しても、「人間の意図した数字」になる。他はどうなんだろう?