一个非常艰苦的面试问题可能是这样的:
int i = Integer.MAX_VALUE;
i += 0.0f;
int j = i;
System.out.println(j == Integer.MAX_VALUE); // true
为什么打印出正确的文字?
乍一看,答案似乎很明显,直到您意识到如果长时间更改int,事情都会变得很奇怪:
long i = Integer.MAX_VALUE;
i += 0.0f;
int j = (int) i;
System.out.println(j == Integer.MAX_VALUE); // false
System.out.println(j == Integer.MIN_VALUE); // true
您可能会想什么呢? Java何时成为JavaScript?
首先,让我解释为什么长时间会产生如此奇怪的结果。
关于+ =的重要细节是它进行隐式强制转换。 您可能会认为:
a += b;
是相同的:
a = a + b;
基本上,除了大部分时间无关紧要之外,还有一个细微的差别:
a = (typeOf(a)) (a + b);
加法的另一个微妙特征是结果是两种类型的“范围更大”。 这意味着:
i += 0.0f;
实际上是:
i = (long) ((float) i + 0.0f);
将Integer.MAX_VALUE转换为浮点数时,会出现舍入错误(因为浮点数的尾数为24位),导致该值比开始时多一个。 即它与:
i = Integer.MAX_VALUE + 1; // for long i
当您再次将Integer.MAX_VALUE + 1转换为int时,将发生溢出,并且具有:
Integer.MIN_VALUE;
j = Integer.MIN_VALUE;
那么,为什么长得到意外的值,而int恰好得到预期的值呢?
原因是当从浮点数舍入到整数时,它会舍入到0,直到最接近的可表示值。 从而:
int k = (int) Float.MAX_VALUE; // k = Integer.MAX_VALUE;
int x = (int) (Integer.MAX_VALUE + 1.0f) // x = Integer.MAX_VALUE;
注意:Float.MAX_VALUE / Integer.MAX_VALUE是1.5845632E29,这真是一个错误,但最好的int可以做到。
简而言之,对于int值Integer.MAX_VALUE,语句i + = 0.0f; 导致该值先跳一(强制转换为浮点数),然后再跳一(强制转换为int值),以便您获得开始时的值。
翻译自: https://www.javacodegeeks.com/2014/10/a-java-conversion-puzzler-not-suitable-for-work-or-interviews.html