C'è una differenza su come java esegue le operazioni usando operatori di scorciatoia da quelli normali?
-
05-07-2019 - |
Domanda
Sto lavorando a un programma Java relativo al triangolo di Pascal.
Ecco come è codificato:
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();
}
e mostra:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
Ma quando ho provato a cambiare il codice in:
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();
}
e come avrai notato, solo l'operatore è cambiato in * =, ma il risultato è:
1
1 1
1 2 0
1 3 3 0
1 4 4 0 0
Qualche idea su cosa deve essere successo? Grazie in anticipo!
Soluzione
È perché stai usando l'aritmetica dei numeri interi nell'ordine sbagliato.
x *= (i - j) / (j + 1);
è uguale a
x = x * ((i - j) / (j + 1));
Le parentesi sono importanti. (i - j) / (j + 1)
nella maggior parte dei casi non è un numero intero, ma java lo arrotonda comunque ad un numero intero.
Il modo in cui l'hai fatto prima
x = x * (i - j) / (j + 1);
la moltiplicazione avviene prima della divisione, quindi non si ottengono errori di arrotondamento.
Altri suggerimenti
Hai cambiato la precedenza alta * con una precedenza bassa * = risultante
x = x * ((i - j) / (j + 1));
invece di
x = (x * (i - j)) / (j + 1);
che probabilmente volevi.
Sembra una divisione intera rispetto all'ordine delle operazioni. Prova ad aggiungere alcune parentesi e penso che alla fine otterrai gli stessi risultati. Se, diciamo, dividi 2/3 in numeri interi, ottieni 0. Quindi è importante se prima fai un po 'di moltiplicazioni.