Ответ 1
long oneYearWithL = 1000*60*60*24*365L;
long oneYearWithoutL = 1000*60*60*24*365;
Ваше первое значение на самом деле длинное (так как 365L
- это long
, а 1000*60*60*24
- integer
, поэтому результат значения multiplying
a long
со значением integer
равен a long
.
Но второе значение является целым числом (так как вы mulitplying значение integer
только с значением integer
. Таким образом, результат будет целым числом 32-bit
. Теперь результат, полученный для этого multiplication
, находится вне действительный диапазон integer.Таким образом, перед тем, как назначить эту переменную, она усекается, чтобы поместиться в допустимый целочисленный диапазон.
Посмотрите на следующий оператор печати: -
System.out.println(1000*60*60*24*365L);
System.out.println(1000*60*60*24*365);
System.out.println(Integer.MAX_VALUE);
При запуске вышеуказанного кода: -
Результат: -
31536000000
1471228928
2147483647
Итак, вы можете видеть разницу.
011101010111101100010010110000000000 -- Binary equivalent of 1000*60*60*24*365L
01111111111111111111111111111111 -- Binary equivalent of Integer.MAX_VALUE
Итак, если вы не добавите это L
в конце своего номера, 4 самых значимых бит будут удалены из первой двоичной строки.
Итак, строка становится...
(0111)01010111101100010010110000000000 -- Remove the most significant bits..
01010111101100010010110000000000 -- Binary equivalent of 1471228928
(который вы получаете как вывод)
ОБНОВЛЕНИЕ: -
Из приведенного выше объяснения вы также можете понять, что даже в первом назначении, если результат вашего multiplication
of integers
до его умножения с помощью 365L
выходит за пределы диапазона, то снова он будет усечен, чтобы соответствовать целочисленный диапазон или преобразовать в 2 complement representation
, если требуется, и тогда только он будет умножен на long value - 365L
.
Например, например:
long thirtyYearWithL = 1000*60*60*24*30*365L;
В приведенном выше примере рассмотрим первую часть - 1000*60*60*24*30
. Результатом этого умножения является: - 2592000000
. Теперь давайте посмотрим, как он представлен в binary equivalent
: -
2592000000 = 10011010011111101100100000000000 -- MSB is `1`, a negative value
01100101100000010011100000000001 -- 2 complement representation
Десятичное представление представления 2 complement
1702967297
. Таким образом, 2592000000
преобразуется в -1702967297
, прежде чем умножается на 365L
. Теперь, поскольку это значение соответствует integer range
, которое: - [-2147483648 to 2147483647]
, поэтому оно не будет усекаться дальше.
Итак, фактический результат будет: -
long thirtyYearWithL = 1000*60*60*24*30*365L;
= 2592000000 * 365L;
= -1702967297 * 365L = -621583063040
Итак, все эти вещи просто рассматривают фактический type
конечного результата при применении арифметической операции. И эта проверка выполняется для каждого временного результата операций, перемещающихся из left to right
(с учетом операторов с ассоциативностью left-to-right
). Если какой-либо временной результат окажется вне допустимого диапазона, то он преобразуется соответствующим образом, чтобы соответствовать требуемому диапазону, прежде чем двигаться вперед при следующей операции.
ОБНОВЛЕНИЕ 2: -
Итак, вместо: -
long thirtyYearWithL = 1000*60*60*24*30*365L;
если вы переместите свой 365L
в начале, тогда вы получите правильный результат: -
long thirtyYearWithL = 365L*1000*60*60*24*30; // will give you correct result
Потому что теперь ваш результат temporary
будет иметь тип long
и способен удерживать это значение.