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

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

0
Jronny 26 Ноя 2009 в 17:06

3 ответа

Лучший ответ

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

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

Такой же как

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

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

Как вы это сделали вначале

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

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

13
dave4420 26 Ноя 2009 в 17:10
Ну моя плохая. Я на самом деле написал этот код на javascript, чтобы воспроизвести результат, но с js все в порядке. Теперь я знаю ... Большое спасибо
 – 
Jronny
26 Ноя 2009 в 17:24

Вы переключили высокий приоритет * на низкий * =, что привело к

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

Вместо того

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

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

5
extraneon 26 Ноя 2009 в 17:13

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

2
bmargulies 26 Ноя 2009 в 17:09