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

Кроме того, безопасно ли выполнять арифметику с разными примитивами, пока вы назначаете в свой список самый широкий примитивный тип?

Это зависит от того, что вы подразумеваете под безопасностью. Это, безусловно, не позволит вам рассмотреть возможность переполнения.

Ответ 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 имеет больший диапазон, чем длинный, но имеет меньший размер.