リンクした質問に対する私の答えを見たので、それを調べて、2番目のシナリオを調べるために必要な変更を加えましょう。
バイナリでは、1.7は次のとおりです。
b1.1011001100110011001100110011001100110011001100110011001100110...
ただし、1.7は倍精度リテラルであり、その値は、最も近い表現可能な倍精度値に丸められた1.7です。
b1.1011001100110011001100110011001100110011001100110011
10進数では、それは正確に次のとおりです。
1.6999999999999999555910790149937383830547332763671875
float a = 1.7と書くと、そのdouble値は再び単精度に丸められ、aは2進値を取得します。
b1.10110011001100110011010
これはまさに
1.7000000476837158
10進数(切り上げに注意してください!)
比較(a <1.7)を行う場合、この単精度値(すべての単精度値は倍精度で表現できるため、丸められないdoubleに変換されます)を元の倍精度値と比較しています。なぜなら
1.7000000476837158 > 1.6999999999999999555910790149937383830547332763671875
比較は正しくfalseを返し、プログラムは「false」を出力します。
では、なぜ結果が0.7と1.7で異なるのでしょうか。それはすべて丸めにあります。単精度数は24ビットです。0.7を2進数で書き留めると、次のようになります。
b.101100110011001100110011 00110011...
(24番目のビットの後にそれがどこにあるかを示すためのスペースがあります)。24ビット目以降の次の桁はゼロであるため、24ビットに丸める場合は切り捨てます。
次に1.7を見てください。
b1.10110011001100110011001 10011001...
先頭があるため1.
、24番目のビットの位置がシフトし、24番目のビットの次の桁が1になり、代わりに切り上げます。