2010-07-26 12 views
6

Sulla mia piattaforma di questa stampa 9223372036854775808.conversione sicura dal doppio al senza segno a 64 bit integer

double x = 1e19; 
std::cout << static_cast<unsigned __int64>(x) << '\n'; 

ho provato Boost.NumericConversion, ma ho ottenuto lo stesso risultato.

Splitting x in 2 parti uguali, quindi sommando le metà convertite si ottiene il risultato corretto. Ma ho bisogno di una soluzione generica da utilizzare in un codice modello.

Grazie in anticipo.

MODIFICA: Questo problema si presenta su Visual Studio 2008, ma non su MinGW. La conversione di 4.0e9 in lavori non firmati va bene.

risposta

10

Sembra che funzioni bene con gcc, ma è problematico in Visual Studio. Vedere Microsoft's answer quanto riguarda questa edizione:

nostro virgola mobile a intero conversioni sono sempre fatto per un intero con segno . In questa particolare custodia usiamo le istruzioni FIST che genera 800. 00 come descritto. Pertanto, non esiste un comportamento definito per la conversione in valori interi a 64 bit senza segno iniziale che sono più grandi del numero intero a 64 bit con segno intero.

Così si può convertire solo i numeri nell'intervallo firmato intero a 64 bit: -9.223.372.036.854.775.808 a +9,223,372,036,854,775,807 (-2^63 ~ 2^63-1).

1

Il comportamento del compilatore non è conforme a C99, richiede che i valori positivi vengano sempre convertiti correttamente, se possibile. Permette solo di deviare da quello per i valori negativi.

L'operazione eseguita remaindering quando un valore di tipo intero è convertito tipo unsigned non necessario eseguita quando un valore di beni tipo flottante viene convertito senza segno tipo. Pertanto, la gamma di valori mobili reali reali è (-1, Utype_MAX + 1).

Per il codice di modello, è possibile testare solo se il valore è maggiore di static_cast<double>(UINT64_MAX/2) ed eseguire il lavoro di riparazione che si sta già facendo. Se questo riguarda solo il test delle costanti, questo dovrebbe essere ottimizzato laddove non è rilevante.

Problemi correlati