2016-06-16 39 views
11

Sto cercando di capire la differenza tra alcuni tipi di dati e la conversione.Qual è la differenza tra il casting long.MaxValue in int e il casting float.MaxValue in int?

public static void ExplicitTypeConversion2() 
    { 
     long longValue=long.MaxValue; 
     float floatValue = float.MaxValue; 
     int integerValue = (int) longValue; 
     int integerValue2 = (int)floatValue; 
     Console.WriteLine(integerValue); 
     Console.WriteLine(integerValue2);    
    } 

Quando eseguo quel blocco di codice, emette:

-1 
-2147483648 

so che se il valore che si desidera assegnare a un numero intero è più grande di quello intero può mantenere, restituisce il valore minimo di numero intero (-2147483648).

Per quanto ne so, long.MaxValue è molto più grande del valore massimo di un numero intero, ma se getto long.MaxValue a int, restituisce -1.

Qual è la differenza tra questi due casting? Penso che anche il primo supponga di restituire -2147483648 invece di -1.

+1

mi chiedo il contrario .... 'int i = (int) long.MaxValue' riempie' I' con '0xFFFFFFFF' che è '-1', quindi è chiaro per me. Mi chiedo perché 'int i = (int) float.MaxValue' finisca in' int.MinValue' che è '0x80000000'. –

risposta

2

Mi spiego:

long longValue=long.MaxValue; 
float floatValue = float.MaxValue; 
int integerValue = (int) longValue; 
int integerValue2 = (int)floatValue; 

Il valore massimo di tempo è 9.223.372.036.854.775.807 o 0x7FFFFFFFFFFFFFFF, complemento quindi 2 di dopo aver ridotto in 0xFFFFFFFF tornerà 0x00000001 con il bit segno meno, rappresentate come -1 in decimale.

Dall'altro lato, il valore massimo di float è 3.40282347E + 38, quindi convertendolo a int arrotondato il valore a 3E + 38 e utilizzando il complemento a 2 dopo averlo ridotto otteniamo il valore esadecimale di 0x80000000 con il segno meno segno , c'è -2147483648 in decimale.

Tutto questo caso si applica agli interi con segno, il risultato sarà diverso su quelli non firmati.

Riferimento:

https://msdn.microsoft.com/en-us/library/system.int64.maxvalue(v=vs.110).aspx

https://msdn.microsoft.com/en-us/library/system.single.maxvalue(v=vs.110).aspx

+0

L'argomento relativo alla conversione da float a int non è corretto. La tua affermazione "3.40282347E + 38, convertendola così in int arrotondato il valore a 3E + 38" è corretta solo su carta e penna, non in un computer – AhmadWabbi

+0

tutto equivale alla rappresentazione interna ... Il trunking di 64 bit Long.Maxvalue a 32 bit int in esadecimale è ** 0xFFFFFFFF ** che è di -1 nella rappresentazione di interi con segno sul complemento a 2. Float.maxvalue rappresentato bitwise come ** 0x7FFFFFFF ** a sua volta è bit a bit uguale a Integer.maxvalue sulla rappresentazione a complemento di due. –

+0

@ JoãoRebelo il float che ha il pattern di bit 0x7FFFFFFF è un NaN, e la rappresentazione interna non ha importanza per un float-> int cast – harold

6

Il valore binario di long.MaxValue è 0111...111111 (uno zero seguito da 63). Quando lanci su int, mantieni i 32 bit più bassi 111...11111. Questo è -1 in decimale, come int è signed e si applica il complemento a due.

+0

In decimale dovrebbe essere "4294967295" ma poiché Int32 ha un valore massimo di 2147483647 quando viene raggiunto questo nubmer inizia il conteggio da - 2147483648 (il suo valore minimo) e quindi raggiunge effettivamente -1. –

+0

@PaulWeiland No. Se 'unsigned', il valore sarebbe' 4294967295'. Ma poiché 'int' è' signed', una sequenza di 32 uni equivale a '-1' in complemento a due. – AhmadWabbi

15

se il valore che si desidera assegnare a un numero intero, più grande di quello intero può mantenere, restituisce il valore minimo di integer

che non è una regola. Le norme pertinenti sono

Per tipi interi in un unchecked contesto (cioè il default):

Se il tipo di origine è maggiore del tipo di destinazione, allora il valore di origine viene troncato da scartando sua “extra "Bit più significativi. Il risultato viene quindi considerato come un valore del tipo di destinazione .

Per flottante> int in un contesto unchecked:

il valore viene arrotondato verso zero al valore integrale più vicino. Se questo valore integrale è compreso nell'intervallo del tipo di destinazione entro , questo valore è il risultato della conversione. In caso contrario, il risultato della conversione è un valore non specificato del tipo di destinazione.

Il chopping di 32 bit iniziali di 0x7fffffffffffffff corrisponde a 0xffffffff ovvero -1.

Non sei mai stato promesso si otterrebbe int.MinValue per quella fuori portata flottante> int cast, ma fare in ogni caso, perché è facile da implementare: istruzione di conversione del 64 cvtss2si rende 0x80000000 per fuori risultati range e simile fistp (il vecchio l'istruzione di conversione x87 utilizzata dal JIT a 32 bit memorizza "il valore intero indefinito" che è 0x80000000.

+0

in C# funziona in base al formato esadecimale? 0x7fffffffffffffff o binario dietro le quinte? Intendo ad esempio la conversione da un tipo all'altro, se converto il valore di esso in binario per controllare altri tipi di bit, quindi decidere se posso mantenere o perdere i dati – Tuncaf

+0

@Tuncaf non c'è alcun formato dietro le quinte. Esadecimale e binario sono solo due modi ugualmente buoni per visualizzare cosa sta succedendo (ma hex è più breve, è l'unica ragione per cui l'ho scelto). – harold

+0

grazie @horald – Tuncaf

Problemi correlati