为什么在下面的代码中从 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
从它的 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 会得到更好的近似值。
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
从它的 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 会得到更好的近似值。