Precedente: Impostare la precisione, Su: Cautela col calcolo in VM [Contenuti][Indice]
La variabile ROUNDMODE
permette di controllare a livello di programma
la modalità di arrotondamento.
La corrispondenza tra ROUNDMODE
e le modalità di arrotondamento IEEE
è mostrata in Tabella 15.4.
Modalità di arrotondamento | Nome IEEE | ROUNDMODE |
---|---|---|
Arrotonda al più vicino, o a un numero pari | roundTiesToEven | "N" o "n" |
Arrotonda verso infinito | roundTowardPositive | "U" o "u" |
Arrotonda verso meno infinito | roundTowardNegative | "D" o "d" |
Arrotonda verso zero (troncamento) | roundTowardZero | "Z" o "z" |
Arrotonda al più vicino, o per eccesso | roundTiesToAway | "A" o "a" |
Tabella 15.4: Modalità di arrotondamento in gawk
ROUNDMODE
ha "N"
come valore di default, ovvero si usa la
modalità di arrotondamento IEEE 754 roundTiesToEven
.
In Tabella 15.4, il valore "A"
seleziona
roundTiesToAway
. Questo è applicabile solo se la versione in uso
della libreria MPFR lo supporta; altrimenti, l’impostazione di ROUNDMODE
ad "A"
non ha alcun effetto.
La modalità di default roundTiesToEven
è la più preferita, ma allo
stesso tempo
la meno intuitiva. Questo metodo fa la cosa ovvia per la maggior parte dei
valori, arrotondandoli per eccesso o per difetto alla cifra più prossima.
Per esempio, arrotondando 1.132 alle due cifre decimali si ottiene 1.13,
e 1.157 viene arrotondato a 1.16.
Tuttavia, se si deve arrotondare un valore posto esattamente a metà strada,
le cose non funzionano come probabilmente si insegna a scuola.
In questo caso, il numero è arrotondato alla cifra pari più prossima.
Così arrotondando 0.125 alle due cifre si arrotonda per difetto a 0.12,
ma arrotondando 0.6875 alle tre cifre si arrotonda per eccesso a 0.688.
Probabilmente ci si è già imbattuti in questa modalità di arrotondamento
usando printf
per formattare numeri a virgola mobile.
Per esempio:
BEGIN { x = -4.5 for (i = 1; i < 10; i++) { x += 1.0 printf("%4.1f => %2.0f\n", x, x) } }
produce il seguente output quando viene eseguito sul sistema dell’autore:103
-3.5 => -4 -2.5 => -2 -1.5 => -2 -0.5 => 0 0.5 => 0 1.5 => 2 2.5 => 2 3.5 => 4 4.5 => 4
La teoria che sta dietro alla regola
roundTiesToEven
è che gli arrotondamenti di
valori equidistanti in eccesso e in difetto si distribuiscono più o meno
uniformemente, con la possibile conseguenza che errori di arrotondamento
ripetuti tendono ad annullarsi a vicenda. Questa è la modalità di
arrotondamento di default per funzioni e operatori di calcolo secondo IEEE 754.
Le altre modalità di arrotondamento sono usate raramente. Gli arrotondamenti
verso l’infinito (roundTowardPositive
) e verso il meno infinito
(roundTowardNegative
) vengono spesso usati per eseguire calcoli su
intervalli, dove si adotta questa modalità di arrotondamento per calcolare
i limiti superiore e inferiore per l’intervallo di valori in uscita.
La modalità
roundTowardZero
può essere usata per convertire numeri a virgola mobile
in numeri interi. La modalità di arrotondamento roundTiesToAway
arrotonda il risultato al numero più vicino, e in caso di equidistanza
arrotonda per eccesso.
Qualche esperto di analisi numerica dirà che la scelta dello stile di arrotondamento ha un grandissimo impatto sul risultato finale, e consiglierà di attendere sino al risultato finale dopo ogni arrotondamento. Invece, spesso si possono evitare problemi legati a errori di arrotondamento impostando all’inizio la precisione a un valore sufficientemente maggiore della precisione desiderata, in modo che il cumulo degli errori di arrotondamento non influisca sul risultato finale. Se si ha il dubbio che i risultati del calcolo contengano un’accumulazione di errori di arrotondamento, occorre, per accertare la cosa, controllare se si verifica una differenza significativa nell’output cambiando la modalità di arrotondamento.
È possibile che l’output sia completamente diverso, se la
libreria C presente nel sistema in uso non si conforma, per printf
,
alla regola IEEE 754
di arrotondamento al valore pari in caso di equidistanza.
Precedente: Impostare la precisione, Su: Cautela col calcolo in VM [Contenuti][Indice]