Есть ли разница в том, как java выполняет операции с использованием быстрых операторов от обычных? - PullRequest
0 голосов
/ 26 ноября 2009

Я работаю над Java-программой, касающейся треугольника Паскаля.

Вот как это закодировано:

for(int i = 0; i < 5; i++){
    for(int j = 0, x = 1; j <= i; j++){
        System.out.print(x + " ");
        x = x * (i - j) / (j + 1);
    }
    System.out.println();
}

и показывает:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1

Но когда я попытался изменить код на:

for(int i = 0; i < 5; i++){
    for(int j = 0, x = 1; j <= i; j++){
        System.out.print(x + " ");
        x *= (i - j) / (j + 1);
    }
    System.out.println();
}

и, как вы могли заметить, только оператор изменился на * =, но результат:

1
1 1
1 2 0
1 3 3 0
1 4 4 0 0

Есть идеи, что должно было случиться? Заранее спасибо!

Ответы [ 3 ]

13 голосов
/ 26 ноября 2009

Это потому, что вы используете целочисленную арифметику в неправильном порядке.

x *= (i - j) / (j + 1);

совпадает с

x = x * ((i - j) / (j + 1));

Скобки важны. (i - j) / (j + 1) в большинстве случаев не является целым числом, но в любом случае java округляет его до целого числа.

То, как ты это сделал первым

x = x * (i - j) / (j + 1);

умножение происходит до деления, поэтому вы не получите ошибок округления.

5 голосов
/ 26 ноября 2009

Вы сменили высокий приоритет * на низкий приоритет * = в результате

x = x * ((i - j) / (j + 1)); 

вместо

x = (x * (i - j)) / (j + 1);

что вы, вероятно, хотели.

2 голосов
/ 26 ноября 2009

Выглядит как целочисленное деление в зависимости от порядка операций. Попробуйте добавить несколько скобок, и я думаю, что вы в конечном итоге добьетесь таких же результатов. Если, скажем, вы поделите 2/3 на целые числа, вы получите 0. Так что важно, если вы сначала умножитесь.

...