Приоритет оператора в Java - PullRequest
5 голосов
/ 13 ноября 2011

В одном примере из http://leepoint.net/notes-java/data/expressions/precedence.html

Следующее выражение

1 + 2 - 3 * 4 / 5

Оценивается как

1 + 2 - 3 * 4 / 5
    = (1 + 2) - ((3 * 4) / 5)
    = 3 - (12/5)
    = 3 - 2 The result of the integer division, 12/5, is 2 .
    = 1

Тогда я увидел другой пример из http://www.roseindia.net/java/master-java/operator-precedence.shtml

Следующее выражение

4 + 5 * 6 / 3

оценивается как

4 + (5 * (6 / 3))

Я немного озадачен тем, как решается, что будет оцениваться первым, когда * и / будут задействованы. В приведенных выше примерах оба, кажется, разница.

Первый пример оценивает 3*5/5 как ((3*4)/5) В то время как второй пример оценивает 5*6/3 as (5*(6/3))

Я знаю, что * и / имеют приоритет над + и - но как насчет того, когда выражение включает в себя * и /. А также почему два приведенных выше примера демонстрируют разные подходы? Один из них не прав?

Редактировать

public class ZiggyTest {  

    public static void main(String[] args) {  
            System.out.println(4 + (5 * (6 / 3)));
            System.out.println(4 + ((5 * 6) / 3));

            System.out.println(1 + 2 - (3 * (4 / 5)));  
            System.out.println(1 + 2 - ((3 * 4) / 5));  
    }  
 } 

Приведенная выше программа выдает результат

14
14
3
1

Почему последние два выхода не одинаковы, если первые дали одинаковый выход.

Ответы [ 3 ]

11 голосов
/ 13 ноября 2011

Я немного озадачен тем, как будет принято решение о том, что будет оцениваться в первую очередь, когда * и / или участвуют

Вот почему у нас есть спецификации:)

Раздел 15.7 - это раздел Спецификации языка Java, который касается порядка оценки, а в разделе 15.17 указано:

Операторы *, / и%:называется мультипликативными операторами.Они имеют одинаковый приоритет и синтаксически левоассоциативны (они группируются слева направо).

Поэтому, когда есть A op1 B op2 C, и оба op1 и op2 равны *, / или % это эквивалентно

(A op1 B) op2 C

Или, если выразиться иначе - вторая связанная статья совершенно неверна в их примере.Вот пример, чтобы доказать это:

int x = Integer.MAX_VALUE / 2;        
System.out.println(x * 3 / 3);
System.out.println((x * 3) / 3);
System.out.println(x * (3 / 3));

Вывод:

-357913942
-357913942
1073741823

Это показывает, что умножение происходит first (приводящее к целочисленному переполнению), а не деление (который будет умножаться на 1).

3 голосов
/ 13 ноября 2011

Вы уверены?

4 + (5 * 6) / 3
4 + 30 / 3
4 + 10
14

4 + 5 * (6 / 3)
4 + 5 * 2
4 + 10
14

Они выдают одинаковый результат, поскольку добавление скобок не приводит к изменению результата. Для вашего другого уравнения скобки действительно меняют результат. Если убрать скобки в уравнениях, которые я решил, правильный путь к результату будет первым.

2 голосов
/ 13 ноября 2011

Второй не так. См. ответ Джона Скита . Мультипликативные операторы оценивают слева направо. Группировка для:

4 + 5 * 6 / 3

должно быть

4 + ((5 * 6) / 3).

В этом случае, однако, неправильная группировка

4 + (5 * (6 / 3))

дает тот же ответ.

...