Unit in the last place
Si definisce unit in the last place (unità in ultima posizione) o unit of least precision (unità di minore precisione), comunemente abbreviato in ulp, il valore assunto in un numero in virgola mobile dalla cifra unitaria in posizione meno significativa,[1] ovvero la distanza fra due numeri macchina consecutivi. L'ulp è adatta come misura dei piccoli errori nelle operazioni atomiche, mentre si presta meno bene ad esprimere gli errori di computazioni più ampie, per cui è comunemente impiegata per esprimere gli errori nell'aritmetica dei calcolatori, meno spesso nell'analisi numerica.[2]
Definizione
modificaIl concetto di ulp è stato introdotto da William Kahan nel 1960, e la definizione originale era la seguente:
- ulp(x) è la distanza fra i due numeri in virgola mobile più vicini a x, anche se x coincide con uno di essi.
Per tenere conto dell'introduzione di valori non numerici nella rappresentazione (come Inf e NaN), la definizione precedente è stata estesa imponendo di considerare solo i due numeri macchina più prossimi a x e finiti, e ponendo ulp(NaN) = NaN.[3]
Una definizione proposta da John Harrison pone ulp(x) come la distanza fra due numeri macchina consecutivi in virgola mobile a e b tra i quali sia compreso x (ovvero a ≤ x ≤ b e a ≠ b), assumendo che l'intervallo dell'esponente non sia limitato superiormente.[4][5]
Le definizioni di Kahan e Harrison coincidono quando applicate a numeri macchina, ma possono differire nel caso di numeri reali, per valori in prossimità di potenze della base. Ad esempio, in base 2 con p cifre, se 1 < x < 1 + 2-p-1 si ha e .[6]
David Goldberg non definisce ulp come una funzione, ma come la quantità espressa dalla cifra meno significativa unitaria del numero macchina, da cui si ricava una funzione che ad un numero in virgola mobile con p cifre x ∈ [be, be+1] associa il valore .[6]
Proprietà
modificaQuando si arrotonda un numero in una rappresentazione in virgola mobile, il valore esatto può differire per difetto o per eccesso fino ad un mezzo del valore della cifra meno significativa nella rappresentazione macchina, per cui si ha un errore assoluto limitato fino a ±0,5 ulp. Considerando un numero in base b con p cifre ed esponente e, nella forma d,d...d × be, il valore del numero varia fra be e b×be, per cui l'errore relativo r associato a 0.5 ulp è compreso tra
ovvero
Si osserva quindi che l'errore relativo corrispondente a 0,5 ulp può variare di un fattore (detto wobble) pari a b. Quando si arrotonda un numero reale con un numero macchina, l'errore relativo è sempre limitato dall'estremo superiore del precedente intervallo, che viene definito come epsilon di macchina.[1]
Lo standard IEEE 754, implementato da praticamente tutto l'hardware in virgola mobile moderno, richiede che i risultati delle operazioni elementari in virgola mobile (addizione, sottrazione, moltiplicazione, divisione, modulo e radice quadrata dal 1985, e fma dal 2008) siano correttamente arrotondati, quindi con un errore limitato a 0,5 ulp. Nel caso delle funzioni trascendenti in generale non è semplice determinare il numero di cifre necessarie nel calcolo per garantire un arrotondamento esatto (problema noto come table-maker's dilemma), e non tutte le librerie numeriche garantiscono l'arrotondamento delle funzioni trascendenti con precisione di 0,5 ulp, ma solitamente hanno almeno la precisione di 1 ulp.[7]
Supporto nei linguaggi di programmazione
modificaIl linguaggio C definisce nella standard library (header <math.h>
) delle funzioni per calcolare il precedente e successivo numero macchina per i numeri in virgola mobile: nextafterf
e nexttowardf
per variabili float
, nextafter
e nexttoward
per variabili double
, nextafterl
e nexttowardl
per variabili long double
.[8]
Le librerie Boost forniscono le funzioni boost::math::float_next
, boost::math::float_prior
, boost::math::nextafter
and boost::math::float_advance
per determinare i numeri in virgola mobile precedenti e successivi, e boost::math::float_distance(a, b)
per calcolare la distanza tra due numeri in virgola mobile.[9]
In Ada i numeri macchina immediatamente precedente e successivo di un valore in virgola mobile possono essere ottenuti con gli attributi 'Pred
e 'Succ
, ad esempio per una variabile X di tipo Float
tali valori sono dati da Float'Pred(X)
e Float'Succ(X)
.[10]
La libreria standard Java include dalla versione 1.5 le funzioni Math.ulp(double)
e Math.ulp(float)
, che permettono di calcolare direttamente il valore ulp di una variabile.
Note
modifica- ^ a b Goldberg, p. 8.
- ^ Muller, p. 1.
- ^ Muller, pp. 1-2.
- ^ Harrison, p. 118.
- ^ Muller, pp. 3-4.
- ^ a b Muller, p. 4.
- ^ William Kahan, A Logarithm Too Clever by Half (TXT), su cs.berkeley.edu, 9 agosto 2004 (archiviato il 27 luglio 2015).
- ^ §7.12.11.3 The nextafter functions, §7.12.11.4 The nexttoward functions (PDF), in ISO/IEC 9899:1999 specification, p. 237.
- ^ Boost float_distance, su boost.org.
- ^ John Barnes, Programming in Ada 2012, Cambridge University Press, 2014, p. 94, ISBN 978-1-107-42481-4.
Bibliografia
modifica- David Goldberg, What Every Computer Scientist Should Know About Floating-Point Arithmetic, in ACM Computing Surveys, marzo 1991.
- John Harrison, A Machine-Checked Theory of Floating Point Arithmetic, in Proceedings of the 1999 International Conference on Theorem Proving in Higher Order Logics, Nizza, Springer, 1999, pp. 113-130.
- Jean-Michel Muller, On the definition of ulp(x), in INRIA Technical Report 5504. ACM Transactions on Mathematical Software, V, N, novembre 2005.