Complement a dos

El complement a dos és una operació matemàtica per a nombres binaris. S'utilitza en informàtica com a mètode per a la representació de nombres amb signe .

El complement a dos d'un nombre de N bits es defineix com el seu complement respecte de 2N. La suma d'un nombre i el seu complement a dos és 2N. Per exemple, per al nombre binari de tres bits 0102 (210 en base 10), el seu complement a 2 és 1102, perquè 0102 + 1102 = 10002 (210 + 610 = 810 , que és 23).

En aquest exemple, el número binari 0102 codifica l'enter amb signe 210. El seu complement a dos, 1102, codifica l'invers: -210. En altres paraules, per invertir el signe de la majoria d'enters (tots menys un), es pot utilitzar el complement a dos de la seva representació binària. La taula de la dreta il·lustra aquesta propietat.

Enters amb signe de 3 bits
Valor
decimal
Representació
complement a dos
0 000
1 001
2 010
3 011
−4 100
−3 101
−2 110
−1 111

El complement a dos es calcula invertint els dígits i afegint un 1: 0102 → 1012 + 12 = 1102

Enters amb signe de 8 bits
Valor
decimal
Representació
complement a dos
0 0000 0000
1 0000 0001
2 0000 0010
... ...
126 0111 1110
127 0111 1111
−128 1000 0000
−127 1000 0001
−126 1000 0010
... ...
−2 1111 1110
−1 1111 1111

Matemàticament, complement a dos d'un nombre natural N que, expressat en el sistema binari està compost per n dígits, es defineix com:

Vegem un exemple: prenem el nombre que, quan s'expressa en binari és , amb 3 dígits, i calculem el seu complement a dos:

, ; i, per tant:

Pot semblar complicat, però és molt fàcil obtenir el complement a dos d'un nombre a partir del seu complement a u, perquè el complement a dos d'un nombre binari és una unitat més gran que el seu complement a u, és a dir:

Noteu que en aquest exemple, on s'ha limitat el nombre de bits a 3, no seria possible distingir entre el -2 i el 7 (el 7 en binari és 1102). En realitat, un nombre en complement a dos s'expressa amb una quantitat arbitrària d'uns a l'esquerra, de la mateixa manera que un nombre binari positiu s'expressa amb una quantitat arbitrària de zeros. Així, el -45, expressat en complement a dos utilitzant 8 bits seria 11010011, mentre que el 19 seria 00010011; i expressat en 16 bits serien 1111111111010011 i 0000000000010011 respectivament.

La utilitat principal del complement a dos es troba en les operacions matemàtiques amb nombres binaris. En particular, la resta de nombres binaris es facilita molt utilitzant el complement a dos: la resta de dos nombres binaris es pot obtenir sumant al minuend el complement a dos del subtrahend.

Signe i bit més significatiuModifica

Quan s'utilitza el complement a 2, el bit més significatiu (el bit de l'esquerra) passa a denotar el signe. Per tant, tots els nombres que comencin amb 02 seran positius, i els que comencin amb 12 negatius.

Màxim valor positiuModifica

En perdre el primer bit, o bit més significant, que representa el signe, el màxim valor positiu Nmax d'un nombre definit per n dígits, passa a ser de:

Nmax = 2n-1 – 1

Així, seguint l'exemple de 3 bits (el valor màxim sense signe seria de 23 = 8), el valor màxim positiu passarà a ser 23-1 – 1 = 22 – 1 = 3.

Màxim valor negatiu (o valor més negatiu)Modifica

El complement a dos de −128 és igual al mateix número binari de 8 bits.
−128 1000 0000
n'invertim els bits 0111 1111
hi sumem 1 1000 0000

Com ja s'ha dit més amunt, amb una sola excepció, qualsevol nombre amb representació de complement a dos, si capgirem tots els dígits i hi sumem 1, s'obté la representació amb complement a dos del seu nombre negatiu. El 12 esdevé –12, el 5 esdevé –5 i el 0 esdevé 0 (amb sobre-passament d'enter o overflow), etc.

En canvi, si fem el complement a dos del valor més negatiu del rang, obtenim el mateix valor negatiu amb overflow. Per exemple, en la mostra de 3 dígits, el valor més negatiu és el –4 (1002). Tot i que esperaríem que el resultat de negar –4 fos +4, com s'ha explicat abans, en un sistema de 3 bits amb complement a dos no existeix la representació del +4. A la taula de la dreta es pot veure el cas en un sistema de 8 bits, on el valor més negatiu seria el –128. Un cop feta la conversió, es manté el mateix valor binari i, per tant el negatiu decimal.

La presència del valor més negatiu pot portar a errors inesperats en programació quan el resultat obté un signe inesperat, o porta a un sobre-passament d'enter inesperat, o porta a comportaments completament estranys. Per exemple:

  • l'operador de negació unària no pot canviar el signe d'un número no zero: –(–128) → –128
  • la multiplicació per –1 retorna, inesperadament, un valor negatiu. (–128) x (–1) → –128
  • la implementació d'un valor absolut pot retornar un número negatiu: abs(–128) → –128
  • la divisió per –1 pot causar una excepció (igual a la causada per la divisió per 0): (–128) / (–1) → error
  • també calculant el romanent o mòdul per –1: (–128) % (–1) → error

Tot i que aquest número és una excepció, és un número vàlid en els sistemes amb complement a dos. Totes les operacions aritmètiques funcionen amb ell, tant com a operand, com a resultat (excepte que hi hagi overflow).

Vegeu tambéModifica