Cバグ?

Telephone Keypad Letter Mapping Fixedを見ていておかしな現象を見つけた。数値を文字コードへ変換する際、7のところだけ "PQRS" と一文字多いので、この部分を吸収するため、

n*25/8-59

とやることでしのいでいた。この "*25/8" の部分を "/.32" に変えると 1B 稼ぐことができるのだが、なぜかうまくいかない。ちょっと調べてみたら、以下のようなことが分かった。

n;main(){
n=56;
printf("%d\n",(int)(n/.32));
printf("%d\n",(int)(n/.32));
}

このプログラムをあなごるサーバーに流すと、結果は、

175
174

となる。何ですかねこの違いは。コンパイラのバグ?それとも、CPUのバグ?

調査の続き

あなごるサーバーに bash を使って以下をサブミットしてみた。

echo '#include
int c;
main(){
c=56;
printf("%d\n",(int)(c/.32));
printf("%d\n",(int)(c/.32));
}'> t.c;gcc -O t.c;./a.out

やはり、出力は、

175
174

となった。ところが、-O を取り除いてやると、

174
174

となった。ということは、gccオプティマイザーのバグか?でも、174 というのも気持ち悪い。

c=56;
printf("%f\n",c/.32);

だと、

175.000000

だしな。浮動小数点の誤差と丸めモードのためなのか?

さらに調べると

printf()の呼び出しを行うと、その後は、174 になるようだ。printf() が丸めモードを変更して、もとに戻していないのではないかな?
また、以下のように fegetround()を呼んでも 174 になった。

#include
int a,b,n;
main(){
n=56;
a=fegetround();
printf("%d\n",(int)(n/.32));
printf("%d\n",(int)(n/.32));
b=fegetround();
printf("%d %d\n",a,b);
}

#libmをリンクしてやらないと fegetround() が解決できない。
両 printf() は、174 を表示したが、ただ、a, b ともに、0 だった。つまり、丸めモードは「0に向かって丸める」モード。
もしかしたら、main() が呼ばれた段階では丸めモードは不定で、fegetround() は不定だと 0 に設定しているのではないだろうか?また、printf() はフォーマッティングのために、丸めモードを fegetround() でチェックしていて、そのため、0 になってしまうのでは?--- 想像だけどつじつまが合うような気がする。
いずれにせよ、バグではなく言語仕様だとしたら、鬱陶しい仕様だな。