Sto eseguendo il porting di un codice C su Scala, che utilizza ampiamente l'aritmetica in virgola mobile. Ho scritto il seguente codice a Scala sulla base di una copia/incolla della versione C:Perché l'aggiunta di parentesi che racchiude cambia il risultato di questa espressione di Scala?
val complimentaryTerms = 2640.96e-6 * sin (f5)
+ 63.52e-6 * sin (2.0 * f5)
+ 11.75e-6 * sin (2.0 * f3 - 2.0 * f4 + 3.0 * f5)
+ 11.21e-6 * sin (2.0 * f3 - 2.0 * f4 + f5)
- 4.55e-6 * sin (2.0 * f3 - 2.0 * f4 + 2.0 * f5)
+ 2.02e-6 * sin (2.0 * f3 + 3.0 * f5)
+ 1.98e-6 * sin (2.0 * f3 + f5)
- 1.72e-6 * sin (3.0 * f5)
- 0.87e-6 * t * sin (f5)
Il risultato di questo calcolo è un po 'fuori da quello che la versione C produce. Tuttavia, se allego l'espressione tra parentesi, in questo modo:
val complimentaryTerms = (2640.96e-6 * sin (f5)
+ 63.52e-6 * sin (2.0 * f5)
+ 11.75e-6 * sin (2.0 * f3 - 2.0 * f4 + 3.0 * f5)
+ 11.21e-6 * sin (2.0 * f3 - 2.0 * f4 + f5)
- 4.55e-6 * sin (2.0 * f3 - 2.0 * f4 + 2.0 * f5)
+ 2.02e-6 * sin (2.0 * f3 + 3.0 * f5)
+ 1.98e-6 * sin (2.0 * f3 + f5)
- 1.72e-6 * sin (3.0 * f5)
- 0.87e-6 * t * sin (f5))
il valore risultante corrisponde esattamente la versione C. Sembra che l'ordine delle operazioni debba essere diverso quando ci sono parentesi che racchiudono contro quando non ce ne sono, ma non capisco perché ciò possa fare la differenza. Qualche idea su cosa sta succedendo qui?
Strano. Un insetto? Perché non provi a semplificare gradualmente l'espressione fino a ottenere l'espressione più semplice che dia una discrepanza? per esempio '2640.96e-6 * sin (f5) + 63.52e-6 * sin (2.0 * f5)' diamo una discrepanza? Cosa succede se si rimuove il coefficiente del primo termine? –
(Puoi anche provare a guardare il codice by emesso. Non è così spaventoso come sembra. Non è come guardare l'assembler x86 (anche se ammette che non è lontano). Cerca di ottenere un'espressione semplice prima però, quindi il bytecode è relativamente Insomma, ho il sospetto che sia qualcosa che ha a che fare con il tipo inferito di Temi complementari –
(Hmmm, potresti anche provare 'println complimentaryTerms.getClass()', e vedere se è lo stesso o no. –