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 で書式を指定しても、「人間の意図した数字」になる。他はどうなんだろう?