2015-12-21 19 views
5

Stavo leggendo http://www.cplusplus.com/doc/tutorial/typecasting/. Si dice che:Conversione tra tipi numerici dello stesso tipo

  • Altrimenti, se la conversione è tra tipi numerici dello stesso tipo (numero intero da intero o variabile a variabile), la conversione è valido, ma il valore è specifico per l'implementazione (e potrebbe non essere portatile).

Ma io davvero non ho capito che cosa fa la citazione di cui sopra intende dire? Qualcuno può spiegarlo usando un semplice esempio? Perché la conversione tra un tipo numerico dello stesso tipo genera un valore specifico dell'implementazione? Qual è il motivo?

risposta

5

Consideriamo il seguente esempio:

long long int lli = 5000000000; 
    long int li; 
    int i; 
    li = lli; 
    i = li; 

Potete prevedere i valori di lli, li e i? O se lo li e lo i hanno lo stesso valore?

La risposta è - i valori dipendono dal numero di byte assegnati per ciascun tipo! I.e. per alcuni casi int è uguale a long int, per gli altri long int è uguale a long long int, ma in generale i tipi di long possono essere più lunghi. Simile (in termini di dimensioni della memoria) per float, double e long double.

+0

Quindi, è possibile che long non sia più grande di int su Alcune delle implementazioni in C++? Conosci questa implementazione? – Destructor

+2

@PravasiMeet Questo è il caso comune in realtà. Visual Studio x86 e x64 e gcc x86 hanno sizeof (long) == sizeof (int) se non mi sbaglio e non sarei sorpreso se clang facesse lo stesso. – Pixelchemist

+0

@Pixelchemist: yes gcc 5.2.0 & clang 3.5.0 ha fatto lo stesso. Vedi demo dal vivo http://melpon.org/wandbox/permlink/IsGDktKO5VUBY0KV e http://melpon.org/wandbox/permlink/6icDnbxu4hAIkwMN. Ho ottenuto 5000000000 come output 3 volte. Ma quando lo eseguo su http://webcompiler.cloudapp.net/ mi dà 5000000000 705032704 705032704 come output. Spero che lo scrittore della risposta originale aggiunga questi collegamenti nella sua risposta. – Destructor

1

Lo snippet si riferisce al restringimento delle conversioni tra i tipi di virgola mobile e integrale. Cioè, afferma che sebbene una conversione tra tipi interi o tra tipi a virgola mobile sia valida, il valore risultante sarà definito dall'implementazione.

Come esempio consideriamo il seguente pezzo di codice:

#include <iostream> 
#include <limits> 

int main() { 
    long long lgm = std::numeric_limits<long long>::max(); 
    std::cout << std::hex << lgm << std::endl; 
    int i = lgm; 
    std::cout << std::hex << i << std::endl; 

    long double ldb = std::numeric_limits<long double>::max(); 
    std::cout << std::hex << ldb << std::endl; 
    double db = ldb; 
    std::cout << std::hex << db << std::endl; 
} 

uscita:

7fffffffffffffff 
ffffffff 
1.18973e+4932 
inf 

Come si può vedere il valore massimo di long long integer supera la capacità di un intero semplice. Tuttavia, è possibile convertire un long long in un int (vale a dire, la conversione è valida), ma poiché lo int non può contenere il valore massimo di uno long long non può esserci una conversione accurata. Pertanto, il valore del risultato int deve essere deciso dall'implementazione. Lo stesso vale per la conversione tra long double e double.

Problemi correlati