任何分母不是 2 的幂的有理数在表示为二进制时将导致无限位数。这里有 8/5 和 7/5。因此,没有精确的二进制表示为浮点数(除非您有无限的内存)。
1.6 的精确二进制表示是 110011001100110011001100110011001100...
1.4 的精确二进制表示是 101100110011001100110011001100110011...
这两个值都有无限位数(1100 不断重复)。
浮点值的精度为 24 位。因此,任何值的二进制表示都将四舍五入为 24 位。如果将给定值四舍五入为 24 位,您将得到:
1.6:110011001100110011001101(十进制 13421773)-向上舍入
1.4:101100110011001100110011(十进制 11744051)-向下舍入
这两个值的指数均为 0(第一位是 2^0 = 1,第二位是 2^-1 = 0.5 等)。
由于 24 位值中的第一位是 2^23,您可以通过将 24 位值(13421773 和 11744051)除以 23 倍来计算精确的十进制值。
值为:1.60000002384185791015625 和 1.39999997615814208984375。
使用浮点类型时,您始终必须考虑它们的精度是有限的。可以精确写为十进制值的值在表示为二进制时可能会向上或向下舍入。转换为 int 不尊重这一点,因为它会截断给定的值。您应该始终使用 Math.Round 之类的东西。
如果您真的需要有理数的精确表示,则需要一种完全不同的方法。由于有理数是分数,因此您可以使用整数来表示它们。这是一个如何实现这一目标的示例。
但是,你不能写 Rational x = (Rational)1.6 那么。您必须编写类似 Rational x = new Rational(8, 5) (或 new Rational(16, 10) 等)的东西。