CÓDIGOS & OPERAÇÕES



Os números naturais podem ser representados por um repertório ordenado de símbolos, munido de uma lei de formação do sucessor que combina caracteres (algarismos) elementares sem limite para o número de posições ocupadas pelo símbolo. Fazendo corresponder símbolos diferentes de um tal repertório pré-ordenado (o conjunto dos números naturais) a cada letra do alfabeto, algarismos e outros elementos em certa ordem arbitrária, podemos representar univocamente cada um desses caracteres pelo lugar (número de ordem, a partir do zero) que ocupam naquela lista. O 'American Standard Code for Information Interchange' (código ASCII) é uma das alternativas (até agora universal para o alfabeto latino, apesar do crescimento do conjunto UCS-Unicode) de codificação para gravar, armazenar e recuperar caracteres assim chamados 'ocidentais'. A lista costuma ser apresentada em forma de tabela bidimensional hexadecimal (com 16 colunas, de '0' a 'F'), por diversas razões mnemotécnicas e de comodidade de leitura, entre elas, a visão geral e fácil localização dos caracteres, a organização hexadecimal dos subconjuntos (algarismos vão do código 30h a 39h, a diferença entre um código de minúscula e de maiúscula é sempre 20h - isto é, de 2 linhas da tabela) e outras regularidades. Aliás, é disso que se trata geralmente em qualquer apresentação tabular de uma série.


A primeira pagina com os 128 simbolos codificados da TABELA ASCII
estendida (American Standard Code for Information Interchange):



0 1 2 3 4 5 6 7 8 9 A B C D E F
0 NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI
1 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US
2 SP ! " # $ % & ' ( ) * + , - . /
3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
4 @ A B C D E F G H I J K L M N O
5 P Q R S T U V W X Y Z [ \ ] ^ _
6 ` a b c d e f g h i j k l m n o
7 p q r s t u v w x y z { | } ~ DEL





Hexadecimais de até 2 dígitos podem ser convertidos pela tabela:

CONVERSAO HEXADECIMAL->DECIMAL ou DECIMAL->HEXADECIMAL (2 dígitos)


0 1 2 3 4 5 6 7 8 9 A B C D E F
0 000 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015
1 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031
2 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047
3 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063
4 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079
5 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095
6 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111
7 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
8 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
9 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
A 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
B 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
C 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
D 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
E 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
F 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255



Por exemplo, o código ASCII da letra maiúscula 'A' = 41 hexadecimal
(tabela ASCII)


0 1 2 3 4 5 6 7 8 9 A B C D E F
0
1
2
3
4 A
5
6
7


E, como 41 em base hexadecimal corresponde a 65 em base decimal,
o código ASCII da letra maiúscula 'A' = 41h = 65d = 4x16+1
(tabela de conversão HEXA>DECIMAL>HEXA)


0 1 2 3 4 5 6 7 8 9 A B C D E F
0
1
2
3
4 065
5
6
7
8
9
A
B
C
D
E
F

Ver http://www.jimprice.com/jim-asc.htm

Considerando

<sp> = space = caracter espaco
<lf> = line feed = caracter pula-linha

codificamos em ASCII (hexadecimal) a expressao 'Arquivo aberto':

A r q u i v o <sp> a b e r t o <lf>
41 72 71 75 69 76 6F 20 61 62 65 72 74 6F 0A


Codificamos em ASCII (decimal) a mesma expressao 'Arquivo aberto':

A r q u i v o <sp> a b e r t o <lf>
65 114 113 117 (etc...)



Uma representação hexadecimal usa 16 símbolos elementares, de 0 a F
Uma representação decimal usa 10 símbolos elementares, de 0 a 9
Uma representação binária usa 2 símbolos elementares, 0 e 1
etc.

Como vimos, o sucessor de um caracter é o seguinte caracter na lista, assim, em decimal, temos a sequência de caracteres


... 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 ...


Agora, imagine padrões de 3 posições supondo esse 'alfabeto' de 10 caracteres elementares (decimal). Falar de 'posições decimais' significa que cada uma delas deve exibir um entre 10 caracteres elementares. Respeitando a ordem indicada para sequência de caracteres elementares, para cada posição, começando do zero, voltaremos ao zero após 10 'movimentos' ao se esgotar o repertório de caracteres elementares. Temos, então, como padrão inicial '0 0 0' e ordenamos as posições da direita para a esquerda.

Recorde a regra de associação já mencionada:
"Dado um padrão inicial, cada caracter mais à direita da associação deve ser substituído pelo seu caracter 'sucessor' no símbolo seguinte do repertório, e que, no caso de esta próxima associação já haver sido atribuída, substituímos pelo sucessor também o caracter imediatamente à esquerda da associação."

000
001
002
...
009 :verifique que ao se 'esgotar' o repertório de caracteres elementares em uma posição, voltamos, naquela posição, ao caracter inicial, obtendo o padrão
000 :mas, "no caso de esta próxima associação já haver sido atribuída, substituímos pelo sucessor também o caracter imediatamente à esquerda", assim

009 tem como sucessor o padrão
010
...
099 tem como sucessor o padrão
100 etc.
...
999

O sucessor de '999' seria '000'? Mas como substituir "pelo sucessor também o caracter imediatamente à esquerda", se esta posição não existe? Na escrita comum, dispomos implicitamente de um número ilimitado de 'posições': depois do '999' (3 posições) vem o '1000' (4 posições). De fato, procedemos como se ao escrever algum padrão decimal estivessem implícitos os zeros à esquerda (e, no caso de frações decimais, também os zeros à direita, caso a omissão dos zeros não esteja servindo de indicador de precisão). Escrever '999' como um padrão particular em uma série infinita de padrões decimais inteiros é como escrever '...000000000000000000000999'. Nas frações decimais, escrever '0,1', 0,01', '0,001' (desconsiderando indicações de precisão) equivale a escrever '0,100000000000000000000000000000...', '0,0100000000000000000000000000000...', '0,00100000000000000000000000000000...', etc.

Nas catracas, nos registradores e em quaisquer dispositivos de tamanho fixo (número finito de posições), o sucessor 'mecânico' do último padrão (isto é, aquele que contém em cada posição o 'último' caracter elementar do repertório) é o primeiro padrão (isto é, aquele que contém em cada posição o 'primeiro' caracter elementar do repertório). Como não tem sentido falar (em dispositivos de tamanho fixo) de uma 'posição mais à esquerda' da 'última posição (possível) à esquerda', o padrão produzido pelo 'mecanismo' não pode refletir ('obedecer') a regra de "modificar o caracter mais à esquerda no caso da associação já haver sido atribuída". Seja qual for o resultado do movimento 'mecânico', este corresponderá a um padrão no interior das suas possibilidades de representação; se estas estiverem esgotadas, qualquer leitura subsequente indicará um padrão já visitado. Se o mecanismo não 'travar' para avanços após alcançar o 'último' padrão (como ponteiros de um relógio), continuidade comum em dispositivos construídos para 'não parar', as etapas intermediárias do movimento mecânico levarão ao padrão inicial (ao avançar, da primeira à última posição, em direção ao 'primeiro' caracter elementar do repertório).

Resumindo, com outro exemplo, para padrões de 3 posições com um 'alfabeto' de 6 'letras' (base 6), teríamos
UUU, UUV, ..., UUZ, UVU, UVV, ..., UVZ, UWU, ..., UZZ, VUU, VUV, ..., VZZ, ..., ZZU, ZZV, ZZW, ZZX, ZZY, ZZZ, UUU, UUV, etc.

U letra inicial _U_ (na segunda posição)
passaria a ser _V_ quando se esgotasse pela PRIMYIRU vez o repertório (de 'U' a 'Z') elementar na primeira posição;
passaria a ser _W_ quando se esgotasse pela SYGUNXU vez o repertório (de 'U' a 'Z') elementar na primeira posição;
passaria a ser _X_ quando se esgotasse pela TYRWYIRU vez o repertório (de 'U' a 'Z') elementar na primeira posição;
e assim por diante, cada posição à esquerda contando os esgotamentos de repertório na posição imediatamente à direita.
U indicação _Z_ significa que já foi esgotado 5 vezes o repertório de 6 caracteres imediatamente à direita (5x6=30 movimentos da primeira posição).
V__ (na terceira posição) indica que já foi esgotado 1 vez o repertório de 6 caracteres imediatamente à direita (1x6=6 movimentos da segunda posição).
__W (na primeira posição) indica que foram feitos 2 movimentos (de U para V e de V para W).
Ussim, o padrão VZW neste sistema posicional de 6 caracteres elementares corresponde a (2 movimentos da primeira posição + 30 movimentos da primeira posição + [6 movimentos da segunda posição, que indicam 6x6=) 36 movimentos da primeira posição =) 68 movimentos da primeira posição, ou 68 movimentos 'unitários', estando, portanto, no lugar 68 da lista ordenada de padrões começando do zero:
UUU 0
UUV 1
UUW 2
...
UVU 6
UVV 7
...
UWU 12
...
UXU 18
...
UYU 24
...
UZU 30
UZV 31
UZW 32
...
UZZ 35
VUU 36
...
VZW 68


Assim, 'converter' uma representação na base 6 para a base 10 é encontrar o padrão decimal correspondente ao mesmo lugar na lista dos padrões na base 6; e, de um modo geral, converter ('codificar') uma representação em outra qualquer é encontrar o padrão correspondente da representação de destino na lista dos padrões da representação de origem.


REPRESENTAÇÃO BINÁRIA DE INTEIROS SEM SINAL
decimal binário hexadecimal
0 0000 0
1 0001 1
2 0010 2
3 0011 3
4 0100 4
5 0101 5
6 0110 6
7 0111 7
8 1000 8
9 1001 9
10 1010 A
11 1011 B
12 1100 C
13 1101 D
14 1110 E
15 1111 F



REPRESENTAÇÃO BINÁRIA DE INTEIROS COM SINAL
(um bit de sinal à esquerda)
EXCESSO_DE_8 COMPLEMENTO_A_2
dec bin hex dec bin hex
-8 0000 0 -8 1000 8
-7 0001 1 -7 1001 9
-6 0010 2 -6 1010 A
-5 0011 3 -5 1011 B
-4 0100 4 -4 1100 C
-3 0101 5 -3 1101 D
-2 0110 6 -2 1110 E
-1 0111 7 -1 1111 F
0 1000 8 0 0000 0
1 1001 9 1 0001 1
2 1010 A 2 0010 2
3 1011 B 3 0011 3
4 1100 C 4 0100 4
5 1101 D 5 0101 5
6 1110 E 6 0110 6
7 1111 F 7 0111 7

COMPLEMENTO A 1, notações em COMPLEMENTO A 2 e por EXCESSO de algum valor

E para representar valores negativos com um mesmo conjunto de símbolos? Independentemente do sistema, decimal, binário, ou qualquer outro, precisamos reservar uma parte do repertório se quisermos representar os inteiros negativos. Que parte reservar? Podemos determinar, por exemplo, que o menor valor representável, um valor negativo portanto, seja escrito com o símbolo que usávamos para o 'zero'. Iremos progredindo através dos sucessores dessa representação inicial, alcançando o símbolo que agora indicará o valor zero, em direção aos positivos, até o fim do repertório de símbolos. Por exemplo, com duas posições decimais, poderíamos fazer o símbolo '00' corresponder ao inteiro negativo -50 (menos cinquenta), o '01' ao -49, e assim por diante, alcançando o símbolo '50', que corresponderia ao valor 0 (zero), o '51' significando o valor positivo 1 (um), o símbolo '52' representando o 2 (dois), até o fim do repertório com o símbolo '99' indicando o valor positivo 49. Escolher o símbolo '50' para o valor zero 'equilibra' o número de negativos e positivos representáveis, a primeira metade (de '00' a '49') dos símbolos para os negativos, e a outra metade para o zero ('50') e para os positivos ('51' a '99'). Quando lemos o padrão '49', o interpretamos como -1 (menos 1); o padrão '50' como o valor zero; e o padrão '89' como o valor ('89' – '50' =) 39. Tal notação representa inteiros positivos e negativos 'por excesso' de 50, isto é, o valor 'lido' excede de 50 o valor 'representado'.

Como dissemos, a escolha da codificação depende do uso pretendido. Se for interessante preservar a ordem original da representação sem sinal, por exemplo, para comparar e indicar qual o maior padrão de um conjunto, a notação 'por excesso' é mais útil.

Mas, para somar ou subtrair, como se comporta uma tal notação 'por excesso'? Continuando com o exemplo anterior, ao somarmos os padrões '51' e '39', obtemos o padrão '90' que, como vimos, representa o valor positivo ('90' – '50' =) 40. Mas o padrão '51' ('por excesso' de 50) corresponde ao valor 1, e o padrão '39' corresponde ao valor negativo ('39' – '50' =) -11 (menos onze). Se convertermos a representação ('por excesso' de 50)de cada parcela para o seu valor correspondente, aquela operação se tornaria (1 – 11 = 40), o que está aritmeticamente equivocado.

A 'soma' de padrões 'por excesso' de algum valor acumula os 'excessos' de cada parcela, aumentando a dificuldade de conversão, já que implica saber de quantas parcelas se trata e de subtrair do resultado o 'excesso' acumulado das parcelas. Um mesmo padrão-resultado deve ser interpretado de modo diferente, segundo o número de parcelas da soma (ou da subtração) que levou a ele.

Como interpretar sempre do mesmo modo um total, independentemente das operações que levaram a ele?

Para 'somar', a notação em 'complemento a 2' é mais eficiente. Desde que o resultado esteja na faixa de representação possível, acrescentar dois padrões em 'complemento a 2', 'positivos' ou 'negativos' leva diretamente resultado em 'complemento a 2', 'positivo' ou 'negativo'. 'Subtrair' certo valor em um dispositivo modular (cíclico) equivale a 'somar' seu complemento (o que falta para chegar ao 'zero' do dispositivo). Podemos fazer o ponteiro das horas 'recuar' 2 horas 'avançando' 10 horas (pois 10 é o que falta para 2 chegar ao 'zero' do relógio).


'Por excesso': da conversão 'sem sinal' subtraímos o excesso.
1001 por excesso de 1000 (oito) corresponde ao inteiro positivo
0001 (um positivo)

0001 por excesso de 1000 (oito) corresponde ao inteiro negativo
1001 (sete negativo)

A notação 'por excesso' preserva a ordem dos inteiros sem sinal.

Em "complemento a 1" completamos 1011 com 0100
0100 é o que "falta" a 1011 para "completar" 1111
Dizemos: o "complemento a 1" de 1011 é 0100
1111 - 1011 = 0100

Para os inteiros negativos, "complemento a 2" = (complemento a 1) + 1
Para os inteiros positivos, "complemento a 2" = inteiro sem alteração

1111 [complemento a 1] 0000 [+1 = complemento a 2] 0001
1110 [complemento a 1] 0001 [+1 = complemento a 2] 0010
.... ................. .... ...................... ....
1000 [complemento a 1] 0111 [+1 = complemento a 2] 1000

O complemento a 1 de 1111 é 0000, isto é, (1111 - 1111 = 0000)
O complemento a 1 de 1010 é 0101, isto é, (1111 - 1010 = 0101)

O (complemento a 1) + 1, ou "complemento a 2", de 1010 é (0101+1=0110)
A sequência 1111 representa, em complemento a 2, o número negativo -1
O (complemento a 1) + 1 de 1111 = 0000+1 = 0001

Duas formas de calcular o complemento a 2 para inteiros negativos:
A sequência 0111 representa o número positivo 7 em complemento a 2
O número -7, em complemento a 2, é o (complemento a 1 de 0111)+1=1001
O número -7, em complemento a 2, é o complemento a 1 de (0111-1)=1001

0010 representa o número positivo 2 em complemento a 2
-2, em complemento a 2, é o complemento a 1 de (0010-1)=1110
-2, em complemento a 2, é o (complemento a 1 de 0010)+1=1110

Atenção! (complemento a 2)
Se tivermos 8 bits, em vez de 4, para escrever inteiros com sinal:
10001001 representa o inteiro negativo - 01110111 (= -119 em decimal)
(complemento a 1 de 10001001) + 1 = 01110110 + 1 = 01110111


início   acima   anterior   próximo