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;