2010-03-16 28 views
5

Si prega di vedere il codice semplice di seguito:Unsigned long con valore negativo

#include <iostream> 
#include <stdlib.h> 

using namespace std; 


int main(void) 
{ 
    unsigned long currentTrafficTypeValueDec; 
    long input; 
    input=63; 
    currentTrafficTypeValueDec = (unsigned long) 1LL << input; 
    cout << currentTrafficTypeValueDec << endl; 
    printf("%u \n", currentTrafficTypeValueDec); 
    printf("%ld \n", currentTrafficTypeValueDec); 
    return 0; 
} 

Perché printf() visualizza il currentTrafficTypeValueDec (unsigned long) con valore negativo?

L'output è:

9223372036854775808 
0 
-9223372036854775808 

risposta

3

Divertimento con punte ...

cout fase di stampa del numero come un Unsigned Long, tutti i 64 bit sono significativi e di stampa come intero senza segno binario (penso che il formato di qui sarebbe %lu).

printf(%u ... considera l'input come un normale intero senza segno (32 bit?). Questo fa sì che i bit da 33 a 64 si interrompano, lasciando zero.

printf(%ld ... considera l'input come un numero con segno a 64 bit e lo stampa appena come tale.

La cosa che potrebbe confondere l'ultimo printf è che fornisce lo stesso valore assoluto di cout, ma con un segno meno. Quando si visualizza come un numero intero senza segno, tutti i 64 bit sono significativi nella produzione del valore intero. Tuttavia, per i numeri firmati, il bit 64 è il bit del segno. Quando il bit di segno è impostato (come nel tuo esempio) indica che i 63 bit restanti devono essere trattati come un numero negativo rappresentato in 2's compliment. I numeri positivi vengono stampati semplicemente convertendo il loro valore binario in decimale. Tuttavia per un numero negativo si verifica quanto segue: Stampare un segno negativo, i bit XOR da 1 a 63 con i bit "1" binari, aggiungere 1 al risultato e stampare il valore senza segno. Eliminando il bit di segno (bit 64) si finisce con 63 bit "0", XORing con bit "1" ti dà 63 "1" bit, aggiungi +1 e l'intera cosa scorre per darti un numero senza segno con bit 64 impostato su '1' e il resto su '0' - che è la stessa cosa che hai ottenuto con cout BUT, come un numero negativo.

Una volta elaborato il motivo per cui la spiegazione di cui sopra è corretta si dovrebbe anche essere in grado di dare un senso di this

13

hai mentito a printf facendolo passare un valore senza segno, mentre la specifica disposizione ha detto che sarebbe stato un firmato uno.

+0

modo interessante di metterlo :) – Tim

17

%d è un formattatore firmato. Reinterpretare i bit di currentTrafficTypeValueDec (2 alla 63a potenza) come signed long fornisce un valore negativo. Quindi printf() stampa un numero negativo.

Forse si desidera utilizzare %lu?

1

la variabile non contiene il suo tipo in sé. Si specifica di stampare il suo tipo. Prova:

printf("%lu \n", currentTrafficTypeValueDec); 

perché ld meand lungo firmato che non è vero.

5

Poiché si sta spostando il 1 nel bit di segno della variabile. Quando lo si stampa come valore firmato, è negativo.

+0

+1, migliore risposta. –

0

Si sta stampando %ld o un decimale con segno lungo. Ecco perché restituisce un valore negativo.

Problemi correlati