2014-10-04 18 views
6

se scrivo codice in C++:C++ doppia a long long

long long d = 999999998.9999999994; 
cout<<d; 

ottengo uscita: 999999999 (arrotondando per eccesso)

Ma l'uscita di questo codice:

long long d = 999999998.9999994994; 
cout<<d; 

è 999999998 (arrotondando per difetto)

È qualcosa a che fare con la precisione. C'è un modo in cui posso cambiare la precisione. La funzione floor() fornisce anche la stessa uscita.

Ho anche notato che se assegno il valore 8.9999994994 o 8.9999999994 a d (variabile precedente). L'output è 8.

+0

È possibile aggiungere in modo esplicito 0.5 e cast doppio a lungo lungo. –

+0

Supporto per C++ 11? I letterali definiti dall'utente potrebbero aiutare. – Yakk

+0

@OleksandrVerhun Puoi farlo, ma se il tuo obiettivo è arrotondare il numero in virgola mobile all'intero più vicino, non dovresti farlo. http://blog.frama-c.com/index.php?post/2013/05/02/nearbyintf1 –

risposta

10

999999998.9999999994 non è esattamente rappresentabile in double, in modo che il valore effettivo è uno dei due numeri rappresentabili su entrambi i lati di 999999998.9999999994 - sia 999999998.99999988079071044921875 o 999999999 (supponendo IEEE-754 binary64 formato), selezionata in modo definito dall'implementazione. La maggior parte dei sistemi arriverà automaticamente al numero più vicino, producendo 999999999.

Il risultato netto è che su quei sistemi quando si scrive 999999998.9999999994 si finisce per avere lo stesso effetto di scrivere 999999999.0. Da qui la conversione successiva produce 999999999 - la conversione da un numero in virgola mobile a un intero tronca sempre, ma qui non c'è nulla da troncare.

Con 999999998.9999994994, i numeri rappresentabili più vicini sono 999999998.999999523162841796875 e 999999998.99999940395355224609375. O uno produce 999999998 dopo il troncamento. Allo stesso modo, con 8.9999999994, i numeri rappresentabili più vicini sono 8.999999999399999950355777400545775890350341796875 e 8.9999999994000017267126168007962405681610107421875 e uno dei due produrrà dopo il troncamento.

4
long long d = 999999998.9999999994; 

Il valore più vicino a 999999998.9999999994 che double può rappresentare è 999999999.0 - ricordare che punti galleggianti hanno precisione finita;).
Pertanto, il troncamento delle cifre decimali produce 999999999 e ciò che viene salvato in d.

Utilizzando un letterale con L -suffix non effettivamente portare a 999999998 essere salvati in d-long double ha una maggiore precisione.

long long d = 999999998.9999994994; 

Il valore più vicino alla 999999998.9999994994 che double può rappresentare in realtà è al di sotto 999999999 - circa 999999998.999999523 sulla mia macchina. Il troncamento delle posizioni decimali successivamente produce 999999998 e viene archiviato in d.