Являются ли целочисленные примитивы Java «ограниченными» MAX_INT типа литья?

я пытался отследить очень странным поведением 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?

Спасибо!

8
задан John Price 17 May 2012 в 18:36
поделиться