2017-04-30 4 views
2

Un point court en C contient 16 bits et le premier bit indique si la valeur est négative ou positive. J'ai un programme C qui est comme suit:C Convertir un court-circuit court en point non signé

int main() { 
    short int v; 
    unsigned short int uv; 
    v = -20000; 
    uv = v; 
    printf("\nuv = %hu\n", uv); 
    return 0; 
} 

Puisque la valeur de v est que je sais négatif le premier bit de la variable est un 1. J'attendre la sortie du programme à égal uv = 52,768 b/c 20,000 + (2^15) = 52,768.

Au lieu de cela, j'obtiens uv = 45536 comme sortie. Quelle partie de ma logique est incorrecte?

+2

Les numéros sont stockés dans le complément à 2 (https://en.wikipedia.org/wiki/Two%27s_complement). Donc, le plus grand nombre non signé (0xFFFF) est en fait -1 – twain249

+2

Les nombres négatifs ne sont pas représentés en définissant simplement le dernier bit. Ils sont représentés en tant que complément binaire, c'est-à-dire tous les bits annulés plus un. Voir http://stackoverflow.com/questions/1049722/what-is-2s-complement – Marian

+0

@Marian Ce message était incroyablement utile. Merci! – RyeGuy

Répondre

5

Le comportement que vous voyez peut être expliqué par les règles de conversion de C:

6.3.1.3 Signé et entiers non signés

1 Lorsqu'une valeur de type entier est converti en un autre type entier autre que _Bool, si la valeur peut être représentée par le nouveau type, elle reste inchangée. 2 Sinon, si le nouveau type est non signé, la valeur est convertie en ajoutant ou en soustrayant plusieurs fois la valeur maximale pouvant être représentée dans le nouveau type jusqu'à ce que la valeur soit dans la plage du nouveau type.

(Cette citation est de C99.)

-20000 ne peut pas être représenté par un unsigned short parce qu'il est négatif. Le type de cible est non signé, donc la valeur est convertie en ajoutant à plusieurs reprises 65536 (qui est USHORT_MAX + 1) jusqu'à ce qu'il soit à portée: -20000 + 65536 est exactement 45536. Notez que ce comportement est mandaté par le standard C et n'a rien à voir avec la représentation réelle des nombres négatifs en mémoire (en particulier, il fonctionne de la même manière même sur les machines utilisant sign/magnitude ou ones' complement).

+1

Le comportement modulo est mandaté par la norme - 'USHORT_MAX' étant' 65536' n'est pas (il pourrait être plus grand) –