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 010₂ (210 en base 10), el seu complement a 2 és 110₂, perquè 010₂ + 110₂ = 1000₂ (210 + 610 = 810, que és 23).
En aquest exemple, el número binari 010₂ codifica l'enter amb signe 210. El seu complement a dos, 110₂, 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.
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: 010₂ → 101₂ + 1₂ = 110₂
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 110₂). 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 significatiu
modificaQuan 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 0₂ seran positius, i els que comencin amb 1₂ negatius.
Màxim valor positiu
modificaEn 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 = 2² – 1 = 3.
Màxim valor negatiu (o valor més negatiu)
modifica−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 (100₂). 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).