分母が 2 の累乗でない有理数は、2 進数で表すと無限の桁数になります。ここに 8/5 と 7/5 があります。したがって、浮動小数点数としての正確な 2 進数表現はありません (無限のメモリがない限り)。
1.6 の正確
なバイナリ表現は 110011001100110011001100110011001100 です... 1.4 の正確なバイナリ表現は 101100110011001100110011001100110011...
両方の値の桁数は無限です (1100 は無限に繰り返されます)。
float 値の精度は 24 ビットです。したがって、任意の値のバイナリ表現は 24 ビットに丸められます。指定された値を 24 ビットに丸めると、次のようになり
ます
。
両方の値の指数は 0 です (最初のビットは 2^0 = 1、2 番目のビットは 2^-1 = 0.5 など)。
24 ビット値の最初のビットは 2^23 であるため、24 ビット値 (13421773 と 11744051) を 2 の 23 で割ることによって正確な 10 進値を計算できます。
値は、1.60000002384185791015625 および 1.39999997615814208984375 です。
浮動小数点型を使用するときは、その精度が有限であることを常に考慮する必要があります。10 進数として正確に記述できる値は、2 進数として表すと切り上げまたは切り捨てられる場合があります。int へのキャストは、指定された値を切り捨てるため、それを尊重しません。常に Math.Round のようなものを使用する必要があります。
有理数の正確な表現が本当に必要な場合は、まったく異なるアプローチが必要です。有理数は分数なので、整数を使用して表すことができます。これを実現する方法の例を次に示します。
ただし、Rational x = (Rational)1.6 と書くことはできません。Rational x = new Rational(8, 5) (または new Rational(16, 10) など) のように記述する必要があります。