2017-03-11 1 views
0

J'ai un tableau de unsigned char et un tableau de seulement char. Je veux comparer les deux pour voir s'ils sont identiques. Parfois, la comparaison échoue même lorsque les bits sont les mêmes.Comparer char non signé avec char signé

Je sais que je peux utiliser memcmp(), mais je suis juste curieux de savoir comment le faire manuellement.

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. 
} 

Même si les valeurs char pourraient être les mêmes, la comparaison dira qu'ils sont différents parce arr1 est déplacé dans un registre à l'aide d'un movzx (déplacer s'étendre zéro), tandis que arr2 est déplacé dans un registre à l'aide d'un movsx (extension de signe de déplacement).

Cela conduit à des problèmes avec des nombres tels que 0x90 où le bit le plus significatif est un. Donc un movsx donc un registre de 32 bits donnera la valeur 0xFFFFFF90 tandis qu'un movzx donnera la valeur 0x90 et l'instruction cmp dira qu'ils sont différents.

+0

Ce comportement est correct. les caractères sont promus en ints en C++ et les caractères signés sont étendus. – doug

+0

@doug thanks doug – Majiick

+0

Notez que 'char' peut être signé ou non signé, selon l'implémentation. Apparemment, le vôtre utilise signé. Sur une implémentation qui utilise unsigned ce problème ne se poserait pas. Pour encadrer la question plus génériquement, au lieu de 'char * arr1;', utilisez 'signed char * array;'. –

Répondre

1

D'accord, il vous suffit de les convertir tous les deux en (char) lors de la comparaison.