Soustraction sans signe moins

Comment puis-je soustraire deux nombres entiers en C sans l’opérateur - ?

 int a = 34; int b = 50; 

Vous pouvez convertir b en valeur négative en utilisant la négation et en ajoutant 1:

 int c = a + (~b + 1); printf("%d\n", c); -16 

C’est la négation du signe du complément à deux. Le processeur le fait lorsque vous utilisez l’opérateur ‘-‘ lorsque vous souhaitez annuler la valeur ou la sous-parsingr.

La conversion de float est plus simple. Juste nier premier bit (shoosh vous a donné un exemple comment faire cela).

MODIFIER:

Ok les gars. J’abandonne. Voici ma version indépendante du compilateur:

 #include  unsigned int adder(unsigned int a, unsigned int b) { unsigned int loop = 1; unsigned int sum = 0; unsigned int ai, bi, ci; while (loop) { ai = a & loop; bi = b & loop; ci = sum & loop; sum = sum ^ ai ^ bi; // add i-th bit of a and b, and add carry bit stored in sum i-th bit loop = loop << 1; if ((ai&bi)|(ci&ai)|(ci&bi)) sum = sum^loop; // add carry bit } return sum; } unsigned int sub(unsigned int a, unsigned int b) { return adder(a, adder(~b, 1)); // add negation + 1 (two's complement here) } int main() { unsigned int a = 35; unsigned int b = 40; printf("%u - %u = %d\n", a, b, sub(a, b)); // printf function isn't compiler independent here return 0; } 

J'utilise unsigned int pour que tout compilateur le traite de la même manière.

Si vous souhaitez soustraire des valeurs négatives, procédez comme suit:

  unsgined int negative15 = adder(~15, 1); 

Nous sums maintenant complètement indépendants des conventions de valeurs signées. Dans mon résultat d'approche, toutes les entrées seront stockées en tant que complément à deux - vous devez donc être prudent avec les plus grandes entrées (elles doivent commencer avec 0 bit).

Pontus a raison, le complément à 2 n’est pas prescrit par la norme C (même s’il s’agit de la norme matérielle de facto). +1 pour les réponses créatives de Phil; voici une autre approche pour obtenir -1 sans utiliser la bibliothèque standard ou l’opérateur -.

C commande trois représentations possibles, vous pouvez donc détecter l’opération en cours et obtenir un -1 différent pour chacune d’elles:

 negation= ~1; if (negation+1==0) /* one's complement arithmetic */ minusone= ~1; else if (negation+2==0) /* two's complement arithmetic */ minusone= ~0; else /* sign-and-magnitude arithmetic */ minusone= ~0x7FFFFFFE; r= a+b*minusone; 

La valeur 0x7FFFFFFFE dépend de la largeur (nombre de “bits de valeur”) du type d’entier qui vous intéresse. si non spécifié, vous avez plus de travail pour le découvrir!

  • + Pas de réglage de bit
  • + Indépendant de la langue
  • + Peut être ajusté pour différents types de nombres (int, float, etc.)
  • – Presque certainement pas votre réponse aux devoirs en C (ce qui est susceptible d’être des bits

Développer ab:

 ab = a + (-b)
     = a + (-1) .b

Fabrication -1:

 float: pi = asin (1,0);
 (avec minusone_flt = sin (3.0 / 2.0 * pi);
 math.h) ou = cos (pi)
                   ou = log10 (0,1)
 complexe: minusone_cpx = (0,1) ** 2;  // je suis au carré
 entier: minusone_int = 0;  minusone_int--;  // ou convertir l'un des flotteurs ci-dessus

Etant donné que le codage d’entiers pour supporter le complément à deux n’est pas obligatoire en C, itérez-le jusqu’à la fin. S’ils veulent que vous sautiez à travers des cerceaux enflammés, inutile d’être efficace à ce sujet!

 int subtract(int a, int b) { if ( b < 0 ) return a+abs(b); while (b-- > 0) --a; return a; } 

Question idiote … probablement idiote!

Si vous voulez le faire pour les flottants, commencez par un nombre positif et changez le bit de son signe comme suit:

 float f = 3; *(int*)&f |= 0x80000000; // now f is -3. float m = 4 + f; // m = 1 

Vous pouvez également le faire pour les doublons en utilisant le nombre entier 64 bits approprié. dans Visual Studio, il s’agit de __int64 par exemple.

  • + Pas de réglage de bit
  • + Indépendant de la langue
  • + Indépendant du type de numéro (int, float, etc.)
  • Nécessite a> b (résultat positif)
  • – Presque certainement pas votre réponse aux devoirs en C (ce qui est susceptible d’être des bits
  •   a - b = c 

    en nous limitant à l’espace numérique 0 <= c <(a + b):

            (a - b) mod (a + b) = c mod (a + b)
     un mod (a + b) - b mod (a + b) = c mod (a + b)
    

    simplifier le second terme:

     (-b) .mod (a + b) = (a + bb) .mod (a + b)
                   = a.mod (a + b)
    

    en remplaçant:

     a.mod (a + b) + a.mod (a + b) = c.mod (a + b)
     2 a.mod (a + b) = c.mod (a + b)
    

    si b> a, alors ba> 0, alors:

     c.mod (a + b) = c
     c = 2 a.mod (a + b)
    

    Donc, si a est toujours supérieur à b, cela fonctionnerait.

    Jetez un coup d’oeil ici: Ajouter / Soustraire en utilisant des opérateurs au niveau des bits

    Je suppose que ça

    b – a = ~ (a + ~ b)

    Style d’assemblage (accumulateur):

     int result = a; result -= b; 

    Pour soustraire en C deux entiers, il vous suffit de:

     int subtract(int a, int b) { return a + (~b) + 1; } 

    Je ne crois pas qu’il existe une solution simple et élégante pour les nombres flottants ou doubles, comme pour les nombres entiers. Vous pouvez ainsi transformer vos nombres flottants en tableaux et appliquer un algorithme similaire à celui simulé ici

    Comme la question demandait que les entiers ne int pas des entiers, vous pouvez implémenter un interpréteur plus petit que celui qui utilise les chiffres de l’église .

    Créez une table de recherche pour chaque cas possible d’int-int!

    Pas testé. Sans utiliser le complément à 2:

     #include  #include  int sillyNegate(int x) { if (x <= 0) return abs(x); else { // setlocale(LC_ALL, "C"); // if necessary. char buffer[256]; snprintf(buffer, 255, "%c%d", 0x2d, x); sscanf(buffer, "%d", &x); return x; } } 

    En supposant que la longueur d'un int soit bien inférieure à 255, et que l'aller-retour snprintf / sscanf ne produira aucun comportement non spécifié (non? Non? Non?).

    La soustraction peut être calculée en utilisant a - b == a + (-b).


    Alternative:

     #include  int moreSillyNegate(int x) { return x * ilogb(0.5); // ilogb(0.5) == -1; } 

    Cela fonctionnerait en utilisant un dépassement d’entier:

     #include int subtractWithoutMinusSign(int a, int b){ return a + (b * (INT_MAX + INT_MAX + 1)); } 

    Cela fonctionne aussi pour les floats (en supposant que vous en fassiez une version…)

    Pour la plage maximale de tout type de données, le complément fournit la valeur négative diminuée de 1 à toute valeur correspondante. ex:
    ~ 1 ——–> -2
    ~ 2 ———> -3
    et ainsi de suite … Je vais vous montrer cette observation en utilisant un petit extrait de code

     #include int main() { int a , b; a=10; b=~a; // b-----> -11 printf("%d\n",a+~b+1);// equivalent to ab return 0; } 

    Sortie: 0
    Remarque: Ceci n’est valable que pour la plage de types de données. moyen pour int type de données, cette règle ne sera applicable que pour la valeur de la plage [-2 147 483 648 à 2 147 483 647]. Thankyou ….. Puisse ceci vous aider

      int num1, num2, count = 0; Console.WriteLine("Enter two numebrs"); num1 = int.Parse(Console.ReadLine()); num2 = int.Parse(Console.ReadLine()); if (num1 < num2) { num1 = num1 + num2; num2 = num1 - num2; num1 = num1 - num2; } for (; num2 < num1; num2++) { count++; } Console.WriteLine("The diferrence is " + count); 
     void main() { int a=5; int b=7; while(b--)a--; printf("sud=%d",a); }