2010-04-05 5 views
2

J'ai décidé de le faire de cette façonC - conversion en 2s complément

  • nombres flip 0 = 1, 1 = 0
  • ajouter 1 à bit de poids faible
  • si carry, boucle jusqu'à tableau [ i] == 0

Mais je suis bloqué sur le dernier point; comment puis-je dire cela dans une boucle conditionnelle?

+0

Que contient array []? – WhirlWind

+4

Pourquoi avez-vous besoin de convertir quelque chose à la représentation compliment 2s? Je crois que tout est déjà stocké de cette façon. – pajton

+2

S'il vous plaît, clarifiez de quoi vous parlez. En ce moment, il est difficile de donner un sens à votre question. Qu'est-ce que tu "convertis en complément 2" et pourquoi? – AnT

Répondre

0

Donc, vous stockez votre nombre sous la forme d'un tableau d'ints, qui représentent des bits. Dans l'exemple de code joint, vous avez oublié d'incrémenter la variable i et de vérifier si elle dépassait la taille de votre baie.

Vous pouvez écrire quelque chose comme ça (je suppose que la taille du tableau est):

for (i = 0; i < 5; i++) 
{ 
    if (array1[i] == 1) 
     array1[i] = 0; 
    else // we found a 0 
     array1[i] = 1; 
     break; 
} 
0

Je ne suis pas tout à fait sûr de ce que vous faites, mais peut-être cela aidera:

#define countof(x) (sizeof(x)/sizeof(x[0])) 

// an 8-bit number 
int byte[8] = {0, 1, 1, 0, 1, 1, 1, 0}; // 1 = on, 0 = off 

// flip all bits 
for (size_t i = 0; i < countof(byte); ++i) 
{ 
    byte[i] = !byte[i]; 
} 

// add one 
for (size_t i = 0; i < countof(byte); ++i) 
{ 
    if (byte[i]) // if on 
    { 
     byte[i] = 0; // "add 1, reset to zero", and carry (no break) 
    } 
    else // if off 
    { 
     byte[i] = 1; // turn on 
     break; // nothing to carry, stop adding 
    } 

} 

(Je ne sais pas comment vous pousser dans la bonne direction sans expliquer simplement le code, désolé. Je pense que vous êtes. assez près cela est encore utile)

Vous voyez, quand vous en ajoutez un, si le bit en est déjà un, remettez-le à zéro et continuez le long des bits. Si le bit est zéro, placez-le à un, puis sortez de la boucle. (Rien à porter, donc nous avons fini d'ajouter.)

Espérons que ça aide. En passant, vous remarquerez que les bits sont stockés "en arrière" dans le code ci-dessus. Le LSB est à l'index 0.

2

Vous parlez d'arithmétique étendue. La plupart des processeurs ont des résultats de dépassement et de débordement de chaque opération d'ajout, mais C ne leur donne pas accès.

Votre problème est que les nombres s'allongent à mesure qu'ils grossissent. Si vous êtes au dernier morceau que vous avez, et que vous devez effectuer, vous avez besoin d'un peu plus! Cela signifie que vous devez réaffecter le tableau de bits (si vous utilisez un tableau).

Bien sûr, une solution plus pratique consiste à utiliser des entiers natifs plutôt que des bits individuels, puisque votre processeur gère déjà très bien le complément deux. Ensuite, vous savez que l'ajout d'un résultat entraîne un report si le nombre d'origine est égal à (unsigned) -1. Le problème fondamental demeure; Si vous devez effectuer le dernier unsigned, vous devez en allouer un autre.

0

Vous pouvez faire complément à 2 d'une manière beaucoup plus facile comme ci-dessous:

  • vont inchangé jusqu'à ce que vous trouverez un 1.
  • juste après avoir obtenu le premier 1, retournez les prochains à venir des 0 à 1 et de 1 à Zeros et continuez à faire cela. si le MSB devient 0, cela signifie qu'un débordement s'est produit.

vous pouvez vérifier la validité de l'algorithme par vous-même.et la mise en œuvre devrait être comme ci-dessous:

// an 8-bit number 
int number[8] = {0, 1, 1, 1, 0, 1, 0, 0}; 
int i; 
bool gotFirstOne = false; 

// flip bits after you first encountered an 1 
for (i = 0; i < 8; i++) 
{ 
    if(gotFirstOne == false){ 
     if(number[i] == 1) { 
      gotFirstOne = true; 
     } 
    } 
    else { 
     number[i] = !number[i]; 
    } 

} 

if(number[7] == 0) { 
    printf("Overflow occurred"); 
} 

Cheers !!!!

0

Ma réponse au complément de 2, rappelez-vous ceci est pour le complément de 12 bits, vous pouvez changer le type de masque ou de nombre entier selon votre condition. Cela fonctionne parfaitement, peut également le faire en utilisant une macro.

int twos_compliment(unsigned short a) 
{ 
    int result; 
    result = 0x0FFF&a; 
    result = (((result&0x800)?(0<<11):(1<<11))|((result&0x400)?(0<<10):(1<<10)) 
      |((result&0x200)?(0<<9):(1<<9))|((result&0x100)?(0<<8):(1<<8)) 
      |((result&0x080)?(0<<7):(1<<7))|((result&0x040)?(0<<6):(1<<6)) 
      |((result&0x020)?(0<<5):(1<<5))|((result&0x010)?(0<<4):(1<<4)) 
      |((result&0x008)?(0<<3):(1<<3))|((result&0x004)?(0<<2):(1<<2)) 
      |((result&0x002)?(0<<1):(1<<1))|((result&0x001)?0:1)); 
    return result=result+1; 
}