Java int 转换为 float 转换为 int 不等于原始 int

AJ_*_*eal 1 java math floating-point

使用这个片段:

    public static void main(String[] args){
        int i = XXX;
        System.out.println( (int) ( (float) i ) );
    }
Run Code Online (Sandbox Code Playgroud)

如果int i = 1234;那么输出是1234

如果int i = Integer.MAX_VALUE;那么输出等于Integer.MAX_VALUE

但是,如果int i = 1234567990;,则输出为1234567936,但不等于i

如果int i = 1235567990;,则输出为1235568000,也不等于i

这个转换数学是如何运作的?

Jon*_*eet 11

这对于浮点数学来说是完全正常的。和int都是float32 位值。float只有大约 7 位有效数字的精度,因为它使用某些位进行标度。当您获得较大的值时,“相邻”float值(即从一个可精确表示的值到下一个值)相距超过 1 - 因此这两个相邻值之间的任何整数都不能精确地表示为float

另一种看待这个问题的方法是鸽巢原理的一个版本:

  • float都有int2^32 种可能的位模式
  • int从每个到一个float值都有一个有效的映射
  • 每个位模式都是有效的int,因此有 2^32 个可能的整数值
  • float还包含值 1.5(以及许多其他非整数,但我们只需要其中一个来证明这一点)
  • 因此,至少两个 int值必须映射到相同的值float,这意味着映射在每种情况下都是不可逆的

请注意,如果您使用double,则没问题 - every 都int可以转换为double然后再转换回int,您将获得原始值。然而,出于同样的原因,使用doubleand long(而不是int)会遇到同样的问题,但使用 64 位而不是 32 位。