я пытался отследить очень странным поведением Java. У меня есть формула, которая включает двойное число, но "гарантированно" дает целочисленный ответ, в частности, 32-битное целое число без знака (с чем, увы, Java не справляется). К сожалению, мои ответы иногда были неверными.
В конце концов я нашел проблему, но поведение по-прежнемуочень странное для меня: двойное
приведение непосредственно к int
, по-видимому, ограничено MAX_INT
для целого числа со знаком, тогда как double
приводится к long
, то есть , затемприводится к int
дает мне ожидаемый ответ (-1; MAX INT 32-битного целого числа без знака, представленного как 32-битное целое число со знаком).
Я написал небольшую тестовую программу:
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"; но прямое приведение дает мне MAX_INT для 32-битного целого числа со знаком. Исходя из фона C ++, я бы понял, если бы он дал мне «нечетное число» вместо ожидаемого -1 (он же «наивный кастинг»), но это меня озадачило.
Итак, на вопрос: является ли это «ожидаемым» поведением в Java (например, любое двойное
приведение непосредственно к int
будет «ограничено» до MAX_INT
)? Приведение делает это для любых неожиданных типов? Я ожидаю, что это будет похоже, например, для short
и byte
; но каково «ожидаемое поведение» при приведении oversized-double к float?
Спасибо!