Si consideri il seguente frammento di codice:In che modo printf e scanf gestiscono i formati di precisione in virgola mobile?
float val1 = 214.20;
double val2 = 214.20;
printf("float : %f, %4.6f, %4.2f \n", val1, val1, val1);
printf("double: %f, %4.6f, %4.2f \n", val2, val2, val2);
quali uscite:
float : 214.199997, 214.199997, 214.20 | <- the correct value I wanted
double: 214.200000, 214.200000, 214.20 |
Capisco che 214.20
ha una rappresentazione binaria infinita. I primi due elementi della prima linea hanno un'approssimazione del valore previsto, ma il l'ultimo sembra non avere approssimazione a tutti, e questo mi ha portato alla seguente domanda:
Come fare il scanf
, fscanf
, Le funzioni printf
, fprintf
(ecc.) Trattano i formati di precisione?
In assenza di precisione, printf
ha stampato un valore approssimativo, ma con %4.2f
ha fornito il risultato corretto. Puoi spiegarmi l'algoritmo usato da queste funzioni per gestire la precisione?
Grazie per aver risposto, anche se la mia domanda è ancora nello stesso posto. In primo luogo, il float NON può contenere il valore esatto di 214.20, quindi come potrebbe recuperarlo SOLO con precisione di% 4.2f e NON con% 4.6f. Cosa ha fatto per riconquistare il valore. Capisco che l'approssimazione è stata fatta, ma COSA E 'STATO USATO IL MODELLO DEL PUNTO CHE HA CAUSATO MEMORIZZATO INTERNAMENTE 214.199997 PER DIVENTARE IL 214.20 E COME CI SIAMO ARRIVATI? –
Non sono sicuro di averti, ma questo è solo il [arrotondamento] (http://en.wikipedia.org/wiki/Rounding). È un puro caso che '% 4.2f' ti dia esattamente il valore che volevi. È ancora "sbagliato" poiché la rappresentazione binaria è * non * equivalente a 214,20 ma a 214,1999969482421875. Ora, se giri "214.1999969482421875" a 6 cifre, ottieni "214.199997" perché la settima cifra è una 9, trasformando la 6 in una 7. Ma quando giri solo fino a 2 cifre, ottieni "214.20" perché la terza cifra è un nove, quindi è necessario aumentare il 9 sulla seconda cifra. Che "trabocca" a 10, trasformando ".19" in ".20". – DarkDust
Oh !! Credo che tu stia cercando di dire che questa operazione è fatta in una rappresentazione decimale, ed è così che il 214.199997 si è formato come un effetto rotondo di doppia precisione. Perché se fosse stato in rappresentazione binaria abbiamo già confermato che 214.20 NON è rappresentabile in binario, con tutte le abilità di arrotondamento utilizzate. –