Java-арифметика int vs. long
Я сделал поиск в google, но я не могу найти то, что ищу. Я пытаюсь найти подробную информацию о том, как работает арифметика на Java. Например, если вы добавляете две длинные пары вместе, это используется с тем же оператором добавления, который используется при добавлении двух ints вместе? Кроме того, что происходит под капотом, когда вы смешиваете longs и ints в арифметических выражениях следующим образом:
long result;
long operand a = 1;
int operand b = 999999999;
result = a + b;
Если кто-то может пролить свет на это или опубликовать ссылки на соответствующие статьи, которые были бы удивительными. Спасибо!
EDIT: Спасибо за ответы. Кроме того, безопасно ли выполнять арифметику с различными примитивами, пока вы назначаете в свой список самый широкий примитивный тип?
Ответы
Ответ 1
при смешивании типов int автоматически расширяется до длинного, а затем добавляются две длинные для получения результата. java language spec имеет хорошие примеры для операций, содержащих разные примитивные типы.
В частности, это типы, в которых каждый примитив будет расширяться, не требуя приведения:
- byte для коротких, int, long, float или double
- short для int, long, float или double
- char для int, long, float или double
- int для long, float или double
- долго плавать или удваивать
- float для двойного
Ответ 2
Смотрите: Конверсии и рекламные акции
В соответствии с этим ваш int
продвигается до long
и затем оценивается.
То же самое происходит, например, с int
+ double
и остальными примитивами. то есть.
System.out( 1 + 2.0 );// prints 3.0 a double
Что касается оператора сложения , я почти такой же, но у меня нет ссылок на него.
Быстрый просмотр источника компилятора показывает, что они разные.
А именно iadd
для добавления int и ladd
для длинного добавления:
Смотрите этот пример кода:
$cat Addition.java
public class Addition {
public static void main( String [] args ) {
int a = Integer.parseInt(args[0]);
long b = Long.parseLong(args[0]);
// int addition
int c = a + a;
// long addition
long d = a + b;
}
}
$javac Addition.java
$
При компиляции генерируется байт-код:
$javap -c Addition
Compiled from "Addition.java"
public class Addition extends java.lang.Object{
public Addition();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: aload_0
1: iconst_0
2: aaload
3: invokestatic #2; //Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
6: istore_1
7: aload_0
8: iconst_0
9: aaload
10: invokestatic #3; //Method java/lang/Long.parseLong:(Ljava/lang/String;)J
13: lstore_2
14: iload_1
15: iload_1
16: iadd
17: istore 4
19: iload_1
20: i2l
21: lload_2
22: ladd
23: lstore 5
25: return
}
Посмотрите на строку 16
, она говорит: iadd
(для добавления int), в то время как строка 22
говорит ladd
(для длинного добавления)
Кроме того, безопасно ли выполнять арифметику с разными примитивами, пока вы назначаете в свой список самый широкий примитивный тип?
Да, а также "безопасно" выполнять арифметику с меньшими размерами, в том смысле, что они не нарушают работу программы, вы просто теряете информацию.
Например, попробуйте добавить Integer.MAX_VALUE к Integer.MAX_VALUE
, чтобы узнать, что произойдет, или int x = ( int ) ( Long.MAX_VALUE - 1 );
Ответ 3
Кроме того, безопасно ли выполнять арифметику с разными примитивами, пока вы назначаете в свой список самый широкий примитивный тип?
Это зависит от того, что вы подразумеваете под безопасностью. Это, безусловно, не позволит вам рассмотреть возможность переполнения.
Ответ 4
это называется арифметической продвижением. подробнее см. http://www.cafeaulait.org/course/week2/22.html
Ответ 5
int a=5;
long b=10;
a+=b;
System.out.println(a);
Основное отличие состоит в том, что при a = a + b
не происходит никакого приведения типов, и поэтому компилятор злится на вас за то, что он не типизируется. Но с a += b
то, что он действительно делает, - это тип b
to a
, совместимый с a
.
Ответ 6
Этот простой пример может устранить сомнения в отношении преобразования типов данных в случае арифметических операций в java.
byte a = 1;
short b = 1;
System.out.println(a+b); //Output = 2
Object o = a+b; //Object becomes int
System.out.println(o.getClass().getName()); //Output = java.lang.Integer
int c = 1;
System.out.println(a+b+c); //Output = 3
o = a+b+c; //Object becomes int
System.out.println(o.getClass().getName()); //Output = java.lang.Integer
long d = 1l;
System.out.println(a+b+c+d); //Output = 4
o = a+b+c+d; //Object becomes long
System.out.println(o.getClass().getName()); //Output = java.lang.Long
float e = 1.0f;
System.out.println(a+b+c+d+e); //Output = 5.0
o = a+b+c+d+e; //Object becomes float
System.out.println(o.getClass().getName()); //Output = java.lang.Float
double f = 1.0;
System.out.println(a+b+c+d+e+f); //Output = 6.0
o = a+b+c+d+e+f; //Object becomes double
System.out.println(o.getClass().getName()); //Output = java.lang.Double
Ниже приведен порядок типов данных по диапазону в java:
byte<short<int<long<float<double
Это порядок, в котором произойдет расширение.
Примечание: float имеет больший диапазон, чем длинный, но имеет меньший размер.