Ayant une formation en mathématiques pures, c'est une approche légèrement plus mathématique pour quiconque s'intéresse.
Si nous commençons avec un entier signé et non signé 8 bits, ce que nous avons est essentiellement les entiers modulo 256, en ce qui concerne l'addition et la multiplication, à condition que le complément de 2 soit utilisé pour représenter des entiers négatifs (et c'est ainsi que tous les processeurs modernes le font) .
Là où les choses diffèrent, c'est à deux endroits: l'un est les opérations de comparaison. Dans un sens, les entiers modulo 256 sont mieux considérés comme un cercle de nombres (comme le font les entiers modulo 12 sur une horloge analogique à l'ancienne). Pour que les comparaisons numériques (x <y) soient significatives, nous devions décider quels nombres sont inférieurs aux autres. Du point de vue du mathématicien, nous voulons incorporer les entiers modulo 256 dans l'ensemble de tous les entiers d'une manière ou d'une autre. Le mappage de l'entier 8 bits dont la représentation binaire est tous des zéros à l'entier 0 est la chose évidente à faire. Nous pouvons ensuite procéder à la cartographie des autres afin que '0 + 1' (le résultat de la mise à zéro d'un registre, disons ax, et de l'incrémentation de un, via 'inc ax') passe à l'entier 1, et ainsi de suite. Nous pouvons faire de même avec -1, par exemple en mappant «0-1» à l'entier -1 et «0-1-1» à l'entier -2. Nous devons nous assurer que cette intégration est une fonction, donc nous ne pouvons pas mapper un seul entier 8 bits à deux entiers. En tant que tel, cela signifie que si nous mappons tous les nombres dans l'ensemble d'entiers, 0 sera là, ainsi que certains entiers inférieurs à 0 et certains supérieurs à 0. Il existe essentiellement 255 façons de le faire avec un entier 8 bits (selon au minimum que vous voulez, de 0 à -255). Ensuite, vous pouvez définir «x <y» en termes de «0 <y - x».
Il existe deux cas d'utilisation courants, pour lesquels la prise en charge matérielle est judicieuse: l'un avec tous les entiers non nuls supérieurs à 0, et l'autre avec une répartition d'environ 50/50 autour de 0. Toutes les autres possibilités sont facilement émulées en traduisant les nombres via un ajout supplémentaire. et sub 'avant les opérations, et la nécessité de cela est si rare que je ne peux pas penser à un exemple explicite dans un logiciel moderne (puisque vous pouvez simplement travailler avec une mantisse plus grande, disons 16 bits).
L'autre problème est celui de la mise en correspondance d'un entier 8 bits dans l'espace des nombres entiers 16 bits. -1 va-t-il à -1? C'est ce que vous voulez si 0xFF est censé représenter -1. Dans ce cas, l'extension du signe est la chose la plus judicieuse à faire, de sorte que 0xFF passe à 0xFFFF. D'un autre côté, si 0xFF était censé représenter 255, alors vous voulez qu'il soit mappé à 255, donc à 0x00FF, plutôt qu'à 0xFFFF.
C'est également la différence entre les opérations de «décalage» et de «décalage arithmétique».
En fin de compte, cependant, cela revient au fait que les int dans le logiciel ne sont pas des entiers, mais des représentations en binaire, et que seuls certains peuvent être représentés. Lors de la conception du matériel, des choix doivent être faits quant à ce qu'il faut faire nativement dans le matériel. Comme avec le complément à 2, les opérations d'addition et de multiplication sont identiques, il est logique de représenter les entiers négatifs de cette façon. Il ne s'agit alors que d'opérations qui dépendent des entiers que vos représentations binaires sont censées représenter.