Java подразумевает длительное поведение

Сегодня я нашел одну из моих программ ошибкой, потому что неявный бросок не работал, лучше говоря, что он не работает, как я ожидаю.

У меня было что-то вроде этого

long normal = 1000*24*3600*1000;
System.out.println("normal :"+normal);

нормальный: 500.654.080

запрос excel, правильный результат вычисления должен быть 86.400.000.000;

Я пошел в руководство java, а максимальное значение для длинного типа данных должно быть 2 ^ 63-1, то есть: 9.223.372.036.854.780.000

то я попытался заставить заклинание длиться, и, похоже, он работает:

    long normal = 1000*24*3600*1000;
    long explicit = 1000*24*3600*1000l; // 1000l <- letter L used at the end for long
    long cast = 1000*(long)(24*3600*1000);

    System.out.println("normal :"+normal);
    System.out.println("explicit :"+explicit );
    System.out.println("cast :"+cast);

нормальный: 500.654.080

Явный: 86.400.000.000

cast: 86.400.000.000

Что я думаю, происходит, так это то, что java вычисляет как целое число a в точке, где происходит целочисленное переполнение.

Должен ли Java неявно отбрасывать эти целые числа?

Ответ 1

В Java при вычислении с помощью integers результат всегда будет integer, независимо от типа переменной, которую вы используете для назначения результата.

Назначение одного (или всех) числовых литералов как длинного - это путь, который вы уже узнали:

long implicit = 1000L*24*3600*1000;

EDIT: как отмечено в комментариях, операнды в Java оцениваются слева направо, поэтому по крайней мере первый операнд слева должен быть назначен как Long

Ответ 2

При использовании чисел без L postfix Java интерпретирует это как integers, номер по умолчанию на языке. Расчеты всегда будут выполняться также в int, поэтому вы столкнетесь с переполнением.

Если вы используете или используете явное значение long, все значения в расчете "продвигаются" /расширены до длинных значений. Это описано здесь в спецификации языка:

http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.6.2

Выражение оценивается перед назначением переменной (у которой есть тип long), поэтому Java не знает о переполнении и ничего не продвигает в вашем первом примере.

Ответ 3

java подразумевает длительное поведение при поведении

В Java существует no "неявное длительное поведение при рождении". Вы должны выполнить его самостоятельно, используя длинный литерал или тип (long). Ваш код этого не делает, поэтому значение рассчитывается в точности int. Если вы хотите точность long, выполните одно из следующих действий:

long normal = 1000L*24*3600*1000;
long normal = 1000*24L*3600*1000;
long normal = 1000*24*3600L*1000;
long normal = 1000*24*3600*1000L;
long normal = (long)1000*24*3600*1000;
long normal = 1000*(long)24*3600*1000;
long normal = 1000*24*(long)3600*1000;
long normal = 1000*24*3600*(long)1000;