2017-03-11 2 views
0

Ich habe ein Array von unsigned char und ein Array von nur char. Ich möchte beide vergleichen, um zu sehen, ob sie gleich sind. Manchmal schlägt der Vergleich fehl, selbst wenn die Bits gleich sind.Vergleicht unsigned char mit signierten Char

Ich weiß, ich kann memcmp() verwenden, aber ich bin nur neugierig, wie es manuell zu tun.

char* arr1; 
unsigned char* arr2; 
... 
if (arr1[i] != arr2[i]) { //move zero extend vs move sign extend 
     std::bitset<8> x(arr1[i]); 
     std::bitset<8> y(arr2[i]); 

     std::cout << x << " " << y << std::endl; //The bits are the same. 
} 

Auch wenn die char-Werte könnten gleich sein, wird der Vergleich sagen, dass sie anders sind, weil arr1 in ein Register verschoben wird unter Verwendung eines movzx (Null verlängern bewegen), während arr2 in ein Register verschoben wird unter Verwendung eines movsx (Zeichen erweitern).

Dies führt zu Problemen mit Zahlen wie 0x90, wobei das höchstwertige Bit ein Eins ist. Daher wird ein movsx so ein 32-Bit-Register den Wert 0xFFFFFF90 ergeben, während ein movzx den Wert 0x90 ergibt und der cmp-Befehl wird sagen, dass sie unterschiedlich sind.

+0

Das ist korrektes Verhalten. Zeichen werden zu Ints in C++ hochgestuft, und vorzeichenbehaftete Zeichen werden vorzeichenerweitert. – doug

+0

@doug danke doug – Majiick

+0

Beachten Sie, dass 'char' abhängig von der Implementierung signiert oder unsigniert sein kann. Anscheinend benutzt Ihr signiert. Bei einer Implementierung, die unsigned verwendet, würde dieses Problem nicht auftreten. Um die Frage generischer zu gestalten, verwenden Sie anstelle von 'char * arr1;' 'signed char * array;'. –

Antwort

1

In Ordnung, Sie müssen nur beide auf eine (char) beim Vergleich werfen.