Есть ли разница в том, как java выполняет операции с использованием быстрых операторов от обычных?

StackOverflow https://stackoverflow.com/questions/1803854

Вопрос

Я работаю над 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

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

Это было полезно?

Решение

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

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

совпадает с

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

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

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

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

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

Другие советы

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

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

вместо

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top