Bytes, números e caracteres

01000010 01111001 01110100 01100101 01110011 00101100 00100000
01101110 01110101 01101101 01100101 01110010 01101111 01110011
00100000 01100101 00100000 01100011 01100001 01110010 01100001
01100011 01110100 01100101 01110010 01100101 01110011 00001010

A memória de qualquer computador é uma sequência de bytes.  Cada byte é uma sequência de 8 bits (dígitos binários) e portanto tem 28 = 256 possíveis valores:

00000000
00000001
00000010

11111110
11111111

Em geral, trabalhamos com blocos de  s  bytes consecutivos, podendo s valer 1, 2, 4 ou até 8.  Cada bloco de s bytes tem 8s bits e portanto pode assumir 28s valores.

Um bloco de bytes pode ser interpretado de três maneiras diferentes:

Esta página discute essas três interpretações.

Números naturais e notação binária

Toda sequência de bits pode ser vista como um número natural em notação binária:  o número natural é a soma das potências de 2 que correspondem aos bits 1.  Por exemplo, a sequência  1101  representa o número  23 + 22 + 20,  igual a 13.  A sequência  1111  representa  23 + 22 + 21 + 20,  igual a 15.

Portanto, toda sequência de s bytes — ou seja, 8s bits — representa um número natural no intervalo (fechado)

0 . . 28s−1.

Se s = 1, por exemplo, o intervalo vai de 0 a 28−1, isto é, de 0 a 255.  Se s = 2, o intervalo vai até 216−1, isto é, até 65535.  Se s = 4, o intervalo vai até 232−1, isto é, até 4294967295. 

Exemplo.   Para que o exemplo caiba na página, considere sequências de apenas 4 bits. Uma tal sequência representa, em notação binária, um número no intervalo  0 . . 24−1:

bits número
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 8
1001 9
1010 10
1011 11
1100 12
1101 13
1110 14
1111 15

Convém imaginar que a tabela é cíclica — ou seja, que o fim da tabela é emendado com o começo — e que as operações aritméticas entre números são executadas módulo 24, seguindo o ciclo.  Por exemplo, o resultado da adição de 1 a 15 é 0, e o resultado da adição de 7 a 10 é 1.

Exercícios 1

  1. Mostre que todo número natural pode ser escrito em notação binária.
  2. Mostre que  2k + 2k−1 + … + 21 + 20 = 2k+1−1, qualquer que seja o número natural k.
  3. Escreva os números 28, 28−1, 216, 216−1, 232 e 232−1 em notação hexadecimal.

Números inteiros e notação complemento-de-dois

Toda sequência de s bytes — ou seja, 8s bits — pode ser interpretada como um número inteiro no intervalo (fechado)

−28s−1 . . 28s−1−1 .

Se s = 1, por exemplo, esse intervalo vai de −27 a 27−1, isto é, de −128 a 127.  Se s = 2, o intervalo vai de −215 a 215−1, isto é, de −32768 a 32767.  Se s = 4, o intervalo vai de −231 a 231−1, isto é, de −2147483648 a 2147483647.

Como determinar o inteiro que uma dada sequência de 8s bits representa?  Comece por interpretar a sequência como um número em notação binária. Digamos que esse número é n. Se a sequência começa com um bit 0, ela representa o inteiro positivo n. Se a sequência começa com um bit 1, ela representa o inteiro estritamente negativo  n − 28s.  Essa maneira de representar inteiros é conhecida como notação complemento-de-dois (= two's complement).

Exemplo.   Para que o exemplo caiba na página, considere sequências de apenas 4 bits. Uma tal sequência representa um número inteiro no intervalo −23 . . 23−1 :

bits inteiro
0000 +0
0001 +1
0010 +2
0011 +3
0100 +4
0101 +5
0110 +6
0111 +7
1000 −8
1001 −7
1010 −6
1011 −5
1100 −4
1101 −3
1110 −2
1111 −1

Convém imaginar que a tabela é cíclica (o fim é emendado com o começo) e que as operações aritméticas entre os números são executadas módulo 24, seguindo o ciclo.  Por exemplo, o resultado da adição de 7 e 1 é −8. Analogamente, o resultado da adição de 5 e −14 é 7.

Exercícios 2

  1. Notação complemento-de-dois.  Mostramos acima como a notação complemento-de-dois transforma em um inteiro negativo qualquer sequência de s bytes que começa com um bit 1. Agora considere a operação inversa. Dado um inteiro n no intervalo −28s−1 . . −1, mostre que a sequência de s bytes que representa n em notação complemento-de-dois, é a mesma sequência de bytes que representa n + 28s em notação binária.
  2. Notação complemento-de-dois.  Mostramos acima como a notação complemento-de-dois transforma em um inteiro negativo qualquer sequência de s bytes que começa com um bit 1. Agora considere a operação inversa. Dado um inteiro n no intervalo −28s−1 . . −1, mostre que basta tomar a sequência de bits que representa o valor absoluto de n em notação binária, depois inverter todos os bits (ou seja, trocar 0 por 1 e 1 por 0), e finalmente somar 1, em binário, ao resultado.
  3. Alternativa para complemento-de-dois.  Suponha, como fizemos no exemplo acima, que dispomos de apenas 4 bits para representar números inteiros. Agora adote a seguinte maneira de interpretar uma sequência de 4 bits. Seja n o número inteiro positivo que os 3 últimos bits representam em notação binária. Se o primeiro bit é 0, então a sequência toda representa o número positivo n. Se o primeiro bit é 1, então a sequência toda representa o número negativo −n.  (Por exemplo, a sequência 1101 representa −5.)  Discuta as desvantagens dessa representação de números inteiros.
  4. Escreva os números 27, 27−1, 215, 215−1, 231 e 231−1 em notação hexadecimal.

Caracteres e a tabela ASCII

Um byte pode ser interpretado como um caractere (letra, dígito, sinal de pontuação, etc.).  Essa interpretação tem por base a tabela ASCII, uma tabela arbitrária mas universalmente aceita que associa um caractere a cada byte. (ASCII é a sigla do American Standard Code for Information Interchange.)  Por razões históricas, a tabela ASCII usa apenas bytes cujo primeiro bit é 0 e portanto, tem apenas 128 linhas.  Eis uma pequena amostra da tabela:

byte caractere
00111111 ?
01000000 @
01000001 A
01000010 B
01000011 C
01100001 a
01100010 b
01100011 c
01111110 ~

O conjunto de caracteres coberto pela tabela é conhecido como alfabeto ASCII.  A parte principal desse alfabeto consiste nos seguintes caracteres:

   ! " # $ % & ' ( ) * + , - . /
0 1 2 3 4 5 6 7 8 9 
: ; < = > ? @
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
[ \ ] ^ _ `
a b c d e f g h i j k l m n o p q r s t u v w x y z
{ | } ~

(O primeiro caractere da lista é um espaço.)  É cômodo usar atalhos verbais ao falar de caracteres ASCII.  Por exemplo, em vez de dizer o caractere A podemos dizer o caractere 65, pois o byte que corresponde a A na tabela ASCII vale 65 em notação binária.

Além dos noventa e cinco caracteres normais, o alfabeto ASCII contém trinta e três caracteres especiais, conhecidos como caracteres de controle. Esses caracteres não são símbolos tipográficos como os outros e por isso precisam ser indicados por uma notação especial: uma barra invertida seguida de um dígito ou letra. Eis os caracteres de controle mais comuns:

byte caractere
00000000 \0 caractere nulo (null)
00001001 \t tabulação horizontal (tab)
00001010 \n fim de linha (newline)
00001011 \v tabulação vertical
00001100 \f fim de página (new page)
00001101 \r carriage return

O caractere  \0  é usado para marcar o fim de uma string e não ocupa espaço algum ao ser exibido; o caractere  \n  marca o fim de uma linha de texto e produz uma mudança de linha ao ser exibido; o caractere  \f  marca o fim de uma página; e assim por diante.  Embora o espaço não seja um caractere de controle, podemos usar a notação \   (barra invertida seguida de um espaço) para torná-lo mais visível.

Os caracteres  \  \t\n\v\f  e  \r  são conhecidos como brancos (= white-spaces). Muitas funções das bibliotecas padrão tratam todos os brancos como se fossem espaços.

O alfabeto ASCII não contém letras com sinais diacríticos, como é, Á, õ, ç, etc.  Cada uma dessas e muitas outras letras é representada por 2 ou mais bytes num esquema de codificação conhecido como UTF-8.  Trataremos disso na página Unicode e UTF-8.

Exercícios 3

  1. Quais são os bytes que representam os caracteres  O,  o,  0  e  \0 ?
  2. Escreva os bytes 01000001, 01000010 e 01000011 em notação hexadecimal.
  3. Escreva, em notação decimal, a sequência de bytes que representa o texto  Um byte tem 8 bits..
  4. Considere os bytes que representam os inteiros  65 67 72 79 85 33 10 51 50 32 43 32 52 51 32 61 32 55 53  em notação binária.  Qual a sequência de caracteres representada pela sequência de bytes?
  5. Familiarize-se com os programas od e hexdump (os nomes são abreviaturas de octal dump e hexadecimal dump).  Esses utilitários exibem, byte-a-byte, o conteúdo de qualquer arquivo dado.

Perguntas e respostas