我试图追踪一些非常奇怪的Java行为。我有一个包含双精度浮点数的公式,但“保证”给出整数答案--具体来说,是无符号32位整数(遗憾的是,Java不擅长处理这种类型)。不幸的是,我的答案有时是错误的。
最终我找到了问题所在,但这个行为仍然对我来说非常奇怪:将一个double
直接强制转换为int
似乎被截断为带符号整数的MAX_INT
, 然而将一个double
强制转换为一个long
, 然后再将其转换为int
会给我预期的答案(-1;表示为有符号32位整数的无符号32位整数的MAX_INT
)。
我写了一个小测试程序:
public static void main(String[] args) {
// This is the Max Int for a 32-bit unsigned integer
double maxUIntAsDouble = 4294967295.00;
long maxUintFromDoubleAsLong = (long)maxUIntAsDouble;
long maxUintFromDoubleAsInt = (int)maxUIntAsDouble;
int formulaTest = (int) (maxUintFromDoubleAsLong * 1.0);
int testFormulaeWithDoubleCast = (int)((long) (maxUintFromDoubleAsLong * 1.0));
// This is a more-or-less random "big number"
long longUnderTest = 4123456789L;
// Max int for a 32-bit unsigned integer
long longUnderTest2 = 4294967295L;
int intFromLong = (int) longUnderTest;
int intFromLong2 = (int) longUnderTest2;
System.out.println("Long is: " + longUnderTest);
System.out.println("Translated to Int is:" + intFromLong);
System.out.println("Long 2 is: " + longUnderTest2);
System.out.println("Translated to Int is:" + intFromLong2);
System.out.println("Max UInt as Double: " + maxUIntAsDouble);
System.out.println("Max UInt from Double to Long: " + maxUintFromDoubleAsLong);
System.out.println("Max UInt from Double to Int: " + maxUintFromDoubleAsInt);
System.out.println("Formula test: " + formulaTest);
System.out.println("Formula Test with Double Cast: " + testFormulaeWithDoubleCast);
}
当我运行这个小程序时,我会得到以下结果:
Long is: 4123456789
Translated to Int is:-171510507
Long 2 is: 4294967295
Translated to Int is:-1
Max UInt as Double: 4.294967295E9
Max UInt from Double to Long: 4294967295
Max UInt from Double to Int: 2147483647
// MAX INT for an unsigned int
Formula test: 2147483647
// Binary: all 1s, which is what I expected
Formula Test with Double Cast: -1
我试图理解的是最后两行。双重转换将给出预期的“-1”;但是直接转换却给出了32位有符号整数的MAX_INT。作为一个C++背景下的人,如果它给我一个“奇数”而不是预期的-1(即“天真的转换”),我会理解的,但是这让我感到困惑。
那么问题来了:这是Java中的“预期”行为吗(例如,任何double直接转换为int都将被“限制”为MAX_INT)?对于任何意外类型,转换是否会执行此操作?例如,我会期望它对于short和byte也是类似的;但是当将超大的double转换为float时,它的“预期行为”是什么?
谢谢!