为什么在以下代码中从int转换为float时会出现值丢失?

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位用于表示分数。

这是一个更详细的解释:

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

 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可以得到更好的近似值。