Una cosa che mi piacerebbe vedere sarebbe un riconoscimento che double
per float
deve essere considerata come una conversione ampliamento, mentre float
a double
si sta riducendo (*). Ciò può sembrare controintuitivo, ma considera cosa significano effettivamente i tipi:
- 0.1f significa "13.421.773,5 / 134.217.728, più o meno 1 / 268.435.456 o così".
- 0.1 significa veramente 3.602.879.701.896.397 / 36.028.797.018.963.968, più o meno 1 / 72.057.594.037.927.936 o così "
Se uno ha un valore double
che rappresenta la migliore rappresentazione della quantità "un decimo" e lo converte in float
, il risultato sarà "13.421.773,5 / 134.217.728, più o meno 1 / 268.435.456 o giù di lì", che è una descrizione corretta del valore.
Al contrario, se uno ha un valore float
che rappresenta la migliore rappresentazione della quantità "un decimo" e lo converte in double
, il risultato sarà "13.421.773,5 / 134.217.728, più o meno 1 / 72.057.594.037.927.936 circa" - un livello di precisione implicita che è sbagliato da un fattore di oltre 53 milioni.
Sebbene lo standard IEEE-744 richieda che la matematica in virgola mobile venga eseguita come se ogni numero in virgola mobile rappresenti esattamente la quantità numerica esattamente al centro del suo intervallo, ciò non dovrebbe implicare che i valori in virgola mobile rappresentino effettivamente quelli esatti quantità numeriche. Piuttosto, il requisito secondo cui i valori devono essere considerati al centro dei loro intervalli deriva da tre fatti: (1) i calcoli devono essere eseguiti come se gli operandi abbiano dei valori precisi; (2) ipotesi coerenti e documentate sono più utili di quelle incoerenti o non documentate; (3) se si intende fare un'ipotesi coerente, nessun'altra ipotesi coerente può essere migliore dell'ipotesi che una quantità rappresenti il centro del suo intervallo.
Per inciso, ricordo circa 25 anni fa, qualcuno inventò un pacchetto numerico per C che utilizzava "tipi di intervallo", ciascuno costituito da una coppia di float a 128 bit; tutti i calcoli verrebbero eseguiti in modo tale da calcolare il valore minimo e massimo possibile per ciascun risultato. Se si eseguisse un grande calcolo iterativo lungo e si ottenesse un valore di [12.53401391134 12.53902812673], si potrebbe essere certi che mentre molte cifre di precisione andavano perse a causa di errori di arrotondamento, il risultato poteva ancora essere ragionevolmente espresso come 12,54 (e non lo era ' veramente 12.9 o 53.2). Sono sorpreso di non aver visto alcun supporto per tali tipi in nessun linguaggio tradizionale, soprattutto perché sembrerebbero adatti a unità matematiche che possono operare su più valori in parallelo.
(*) In pratica, è spesso utile utilizzare valori di precisione doppia per contenere calcoli intermedi quando si lavora con numeri a precisione singola, quindi dover usare un typecast per tutte queste operazioni potrebbe essere fastidioso. Le lingue potrebbero aiutare avendo un tipo "fuzzy double", che eseguirà i calcoli come double, e potrebbe essere liberamente trasmesso da e verso single; ciò sarebbe particolarmente utile se le funzioni che accettano parametri di tipo double
e di ritorno double
potrebbero essere contrassegnate in modo da generare automaticamente un sovraccarico che accetta e restituisce invece "fuzzy double".