为什么在下面的代码中从 int 转换为 float 时会丢失值?

Why there is loss of value when converting from int to float in the below code?

int value1 = 123456789;
float value2 = value1;
System.out.println(value1);
System.out.println(value2);

输出:

123456789
123456792

float 类型使用与 int 相同的位数(32 位)来表示比 int 仅用于表示整数更大范围内的浮点数。

这会导致精度损失,因为并非每个 int 数字都可以用 float 准确表示。只有24位用于表示数字的小数部分(包括符号位),而其他8位用于表示指数。

如果将此 int 值分配给 double,则不会有任何精度损失,因为 double 有 64 位,其中超过 32 位是用于表示分数。

这里有更详细的解释:

123456789 作为 int 的二进制表示是:

00000111 01011011 11001101 0001 0101

使用the following formula :

从它的 32 位构造一个单精度浮点数
(-1)^sign * 1.b22 b21 ... b0 * 2^(e-127)

其中 sign 是最左边的位 (b31)。 b22到b0是小数位,b30到b23位是指数e.

因此,当您将int 123456789 转换为float 时,您只能使用以下25 位:

00000111 01011011 11001101 00010101
-    --- -------- -------- -----

我们可以安全地去除任何前导零(符号位除外)和任何尾随零。这给您留下了我们必须丢弃的 3 个最低有效位。我们可以减去 5 得到 123456784:

00000111 01011011 11001101 00010000
-    --- -------- -------- -----

或加 3 得到 123456792:

00000111 01011011 11001101 00011000
-    --- -------- -------- -----

显然加 3 会得到更好的近似值。