2014-01-07 20:18:51 +0000 2014-01-07 20:18:51 +0000
369
369

Se as máquinas de 32 bits só conseguem lidar com números até 2^32, porque é que posso escrever 1000000000000 (triliões) sem que a minha máquina falhe?

Os computadores de 32 bits só podem armazenar números inteiros assinados até 231 - 1. É por isso que ficámos sem endereços IPv4 e entrámos na era dos 64 bits.

No entanto, o número 231 - 1 (2.147.483.647) não é tão grande como o número 1 trilião (1.000.000.000.000.000) que eu pareço ser capaz de mostrar bem sem que a minha máquina falhe.

Alguém pode explicar porque é que isto acontece?

Respostas (18)

784
784
784
2014-01-07 20:31:38 +0000

Respondo à sua pergunta fazendo-lhe uma pergunta diferente:

Como conta com os seus dedos até 6?

É provável que conte até ao maior número possível com uma mão, e depois passe para a segunda mão quando ficar sem dedos. Os computadores fazem a mesma coisa, se precisarem de representar um valor superior ao que um único registo pode conter, utilizarão múltiplos blocos de 32 bits para trabalhar com os dados.

395
395
395
2014-01-07 20:36:34 +0000

Está correcto que um inteiro de 32 bits não pode conter um valor superior a 2^32-1. Contudo, o valor deste inteiro de 32-bit e a forma como aparece no seu ecrã são duas coisas completamente diferentes. A string impressa “1000000000000” não é representada por um inteiro de 32-bit na memória.

Para exibir literalmente o número “1000000000000” são necessários 13 bytes de memória. Cada byte individual pode conter um valor de até 255. Nenhum deles pode conter o valor inteiro, numérico, mas interpretado individualmente como caracteres ASCII (por exemplo, o caracter “0” é representado pelo valor decimal 48, valor binário 00110000), podem ser encadeados num formato que faça sentido para si, um humano.


Um conceito relacionado na programação é typecasting, que é como um computador interpretará um determinado fluxo de 0s e 1s. Tal como no exemplo acima, pode ser interpretado como um valor numérico, um carácter, ou mesmo algo completamente diferente. Enquanto um inteiro de 32 bits pode não ser capaz de conter um valor de 1000000000000, um número de ponto flutuante de 32 bits será capaz de, utilizando uma interpretação completamente diferente.

Quanto à forma como os computadores podem trabalhar e processar números grandes internamente, existem inteiros de 64 bits (que podem acomodar valores até 16-biliões de biliões), valores de ponto flutuante, bem como bibliotecas especializadas que podem trabalhar com números arbitrariamente grandes.

190
190
190
2014-01-07 21:37:16 +0000

Antes de mais, os computadores de 32 bits podem armazenar números até 2³²-1 ** numa única palavra de máquina. Palavra máquina é a quantidade de dados que a CPU pode processar de uma forma natural (ou seja, as operações sobre dados desse tamanho são implementadas em hardware e são geralmente mais rápidas de executar). As CPUs de 32 bits utilizam palavras que consistem em 32 bits, podendo assim armazenar números de 0 a 2³²-1 * numa palavra.

Segundo, 1 trilião e 1000000000000 são duas coisas diferentes.

  • 1 trilião é um conceito abstracto de número
  • 1000000000000 é texto

Ao premir 1 uma vez e depois 0 12 vezes está a escrever texto. 1 entradas 1, 0 entradas 0. Veja? Você está a digitar caracteres. Os caracteres não são números. As máquinas de escrever não tinham CPU ou memória e estavam a lidar muito bem com esses “números”, porque é apenas texto.

** Prova de que 1000000000000 não é um número, mas texto:** pode significar 1 trilião (em decimal), 4096 (em binário) ou 281474976710656 (em hexadecimal). Tem ainda mais significados em sistemas diferentes. O significado de 1000000000000 é um número e armazená-lo é uma história diferente (voltaremos a ele dentro de momentos).

Para armazenar o texto (na programação chama-se string) 1000000000000 são necessários 14 bytes (um para cada caractere mais um byte terminante NULL que basicamente significa “a string termina aqui”). Isso são 4 palavras de máquina. 3 e meia seria suficiente, mas como eu disse, as operações nas palavras da máquina são mais rápidas. Vamos supor que ASCII é usado para armazenamento de texto, então na memória será assim: (convertendo os códigos ASCII correspondentes a 0 e 1 para binário, cada palavra numa linha separada)

00110001 00110000 00110000 00110000
00110000 00110000 00110000 00110000
00110000 00110000 00110000 00110000
00110000 00000000 00000000 00000000

Quatro caracteres cabem numa palavra, o resto é movido para a próxima. O resto é movido para a palavra seguinte até que tudo (incluindo o primeiro byte NULL) encaixe.

Agora, de volta ao armazenamento de números. Funciona tal como com o texto a transbordar, mas eles são encaixados da direita para a esquerda. Pode parecer complicado, por isso aqui fica um exemplo. Para simplificar, vamos assumir que:

  • o nosso computador imaginário usa decimal em vez de binário
  • um byte pode conter números 0..9
  • uma palavra consiste em dois bytes

Aqui está uma memória vazia de 2 palavras:

0 0
0 0

Vamos armazenar o número 4:

0 4
0 0

Agora vamos adicionar 9:

1 3
0 0

Note que ambos os operandos caberiam em um byte, mas não o resultado. Mas temos outro pronto a usar. Agora vamos armazenar 99:

9 9
0 0

Mais uma vez, usámos o segundo byte para armazenar o número. Vamos adicionar 1:

0 0
0 0

Whoops… Isto chama-se “overflow” de integer e é uma causa de muitos problemas graves, por vezes muito caros .

Mas se esperamos que o overflow aconteça, podemos fazer isto:

0 0
9 9

E agora acrescente 1:

0 1
0 0

Torna-se mais claro se removermos espaços byte-separating e novas linhas:

0099 | +1
0100

Prevemos que o overflow pode acontecer e podemos precisar de memória adicional. Manipular números desta forma não é tão rápido como com números que cabem em palavras únicas e tem de ser implementado em software. Adicionar suporte para números de duas-32 bits a um CPU de 32 bits torna-o efectivamente um CPU de 64 bits (agora pode funcionar com números de 64 bits nativamente, certo?).

Tudo o que descrevi acima aplica-se à memória binária com bytes de 8 bits e palavras de 4 bytes também, funciona praticamente da mesma forma:

00000000 00000000 00000000 00000000 11111111 11111111 11111111 11111111 | +1
00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000000

A conversão desses números para o sistema decimal é complicada, no entanto. (mas funciona muito bem com hexadecimal ](https://math.stackexchange.com/q/597019))

40
40
40
2014-01-07 23:06:37 +0000

Também é capaz de escrever “ESTA DECLARAÇÃO É FALSA” sem que o seu computador falhe :) A resposta de @Scott é spot-on para certos quadros de cálculo, mas a sua questão de “escrever” um grande número implica que é apenas texto simples, pelo menos até ser interpretado.

Edit: agora com ~~ sem sarcasmo~~~ mais informação útil sobre diferentes formas de um número poder ser armazenado na memória. Vou descrevê-los com número mais elevado, ou seja, em termos de que um programador moderno pode estar a escrever código antes de ser traduzido para código de máquina para execução.

Os dados num computador têm de ser restringidos a um determinado tipo, e uma definição informática desse tipo descreve que operações podem ser executadas nesses dados e como (ou seja, comparar números, concatenar texto ou XOR um booleano). Não se pode simplesmente adicionar texto a um número, tal como não se pode multiplicar um número por texto para que alguns destes valores possam ser convertidos entre tipos.

Comecemos por unsigned integers. Nestes tipos de valores, todos os bits são utilizados para armazenar informação sobre dígitos; o seu é um exemplo de um inteiro de 32 bits sem assinatura onde qualquer valor de 0 a 2^32-1 pode ser armazenado. E sim, dependendo da linguagem ou arquitectura da plataforma utilizada poderá ter inteiros de 16 bits ou inteiros de 256 bits.

E se quiser ficar negativo? Intuitivamente, signed integers é o nome do jogo. A convenção é atribuir todos os valores de -2^(n-1) a 2^(n-1)-1 - desta forma evitamos a confusão de ter de lidar com duas formas de escrever +0 e -0. Assim, um inteiro de 32 bits assinado teria um valor de -2147483648 a 2147483647. É fixe, não é?

Ok, já cobrimos números inteiros que são números sem uma componente decimal. Expressá-los é mais complicado: a parte não-inteira só pode, sensatamente, estar algures entre 0 e 1, pelo que cada bit extra utilizado para descrevê-los aumentaria a sua precisão: ½, ¼, 1/8… O problema é que não se pode expressar com precisão uma simples decimal 0.1 como uma soma de fracções que só podem ter poderes de dois no seu denominador! Não seria muito mais fácil armazenar o número como um número inteiro, mas concordar em colocar o ponto de radix (decimal) em vez disso? Isto é chamado de números de ponto fixo, onde armazenamos 1234100, mas concordamos numa convenção para o ler como 1234.100.

Um tipo relativamente mais comum utilizado para os cálculos é o floating point. A forma como funciona é muito simples, usa um bit para armazenar o valor do sinal, depois alguns para armazenar expoente e significante. Existem padrões que definem tais alocações, mas para um 32-bit float o número máximo que se pode armazenar é um

(2 - 2^-23) * 2^(2^7 - 1) ≈ 3.4 * 10^38

Isto, no entanto, vem com o custo da precisão. O JavaScript disponível nos browsers usa flutuadores de 64 bits, e ainda não consegue acertar as coisas. Basta copiar isto para a barra de endereços e pressionar enter. Spoiler alert: o resultado é not going to be 0.3.

javascript:alert(0.1+0.2);

Há mais tipos alternativos como Microsoft .NET 4.5’s BigInteger , que teoricamente não tem limites superiores ou inferiores e tem que ser calculado em “lotes”; mas talvez as tecnologias mais fascinantes sejam aquelas que understand mathema, como o motor Wolfram Mathematica, que pode trabalhar precisamente com valores abstratos como infinity .

31
31
31
2014-01-07 21:58:50 +0000

A chave é entender como computadores encode numbers.

True, se um computador insiste em armazenar números usando uma simples representação binária do número usando uma única palavra (4 bytes num sistema de 32 bits), então um computador de 32 bits só pode armazenar números até 2^32. Mas existem muitas outras formas de codificar números, dependendo do que se pretende alcançar com eles.

Um exemplo é como os computadores armazenam números de ponto flutuante. Os computadores podem usar um monte de maneiras diferentes para codificá-los. A norma IEEE 754 define regras para a codificação de números maiores que 2^32. Grosseiramente, os computadores podem implementar isto dividindo os 32 bits em diferentes partes representando alguns dígitos do número e outros bits representando o tamanho do número (ou seja, o expoente, 10^x). Isto permite um amanho muito maior de números em termos de tamanho, mas compromete a precisão (o que é OK para muitos fins). Claro que o computador também pode usar mais do que uma palavra para esta codificação aumentando a precisão da magnitude dos números codificados disponíveis. A simples versão 32 decimal da norma IEEE permite números com cerca de 7 dígitos decimais de precisão e números até cerca de 10^96 em magnitude.

Mas existem muitas outras opções se precisar da precisão extra. Obviamente pode usar mais palavras na sua codificação sem limites (embora com uma penalização de desempenho para converter para dentro e fora do formato codificado). Se quiser explorar uma forma de o fazer, existe um grande add-in open-source para Excel que utiliza um esquema de codificação que permite centenas de dígitos de precisão nos cálculos. O add-in é chamado Xnumbers e está disponível aqui . O código está no Visual Basic que não é o mais rápido possível mas tem a vantagem de ser fácil de entender e modificar. É uma excelente forma de aprender como os computadores conseguem codificar números mais longos. E você pode brincar com os resultados dentro do Excel sem ter que instalar qualquer ferramenta de programação.

24
24
24
2014-01-07 23:47:36 +0000

Está tudo na sua pergunta.

Você pode escrever o número que quiser em papel. Tente escrever um trilião de pontos numa folha de papel branco. É lento e ineficaz. É por isso que temos um sistema de 10 dígitos para representar esses grandes números. Temos até nomes para grandes números como “milhões”, “triliões” e mais, por isso não se diz one one one one one one one one one one one... em voz alta.

processadores de 32 bits são concebidos para funcionarem de forma mais rápida e eficiente com blocos de memória que têm exactamente 32 dígitos binários. Mas nós, pessoas, normalmente usamos um sistema numérico de 10 dígitos, e computadores, sendo electrónicos, usam um sistema de 2 dígitos binário ). Os números 32 e 64 são apenas potências de 2, assim como um milhão e um trilião são potências de 10. É mais fácil para nós funcionar com estes números do que com multidões de 65536, por exemplo.

Partimos grandes números em dígitos quando os escrevemos em papel. Os computadores dividem os números em um número maior de dígitos. Podemos escrever qualquer número que quisermos, e os computadores também o podem fazer, se os concebermos.

15
15
15
2014-01-08 00:42:45 +0000

32bit e 64bit referem-se a endereços de memória. A memória do seu computador é como as caixas postais, cada uma com um endereço diferente. A CPU (Unidade Central de Processamento) utiliza esses endereços para endereçar as localizações da memória na sua RAM (Random Access Memory). Quando o CPU só podia tratar de endereços de 16 bits, só podia utilizar 32mb de RAM (que na altura parecia enorme). Com 32bit passou para 4+gb (o que parecia enorme na altura). Agora que temos endereços de 64bit a RAM passa para terabytes (o que parece enorme). Contudo o programa é capaz de alocar múltiplos blocos de memória para coisas como armazenar números e texto, isso é com o programa e não está relacionado com o tamanho de cada endereço. Assim um programa pode dizer à CPU, vou utilizar 10 blocos de endereços de armazenamento e depois armazenar um número muito grande, ou uma cadeia de 10 letras ou o que quer que seja. Nota lateral: os endereços de memória são apontados por “apontadores”, portanto o valor de 32 e 64 bits significa o tamanho do apontador utilizado para aceder à memória.

13
13
13
2014-01-08 06:44:38 +0000

Porque a exibição do número é feita utilizando caracteres individuais e não inteiros. Cada dígito do número é representado com um carácter separado literal, cujo valor inteiro é definido pela codificação utilizada, por exemplo 'a' é representado com o valor ascii 97, enquanto '1' é representado com 49. Verifique o quadro ascii aqui . Para visualizar tanto o “a” como o “1” é o mesmo. São caracteres literais, não números inteiros. Cada literal de caracteres pode ter um valor máximo de 255 em plataforma de 32 bits, armazenando o valor em 8 bits ou 1 byte (Isto depende da plataforma, no entanto 8 bits é o tamanho de caracteres mais comum), assim podem ser agrupados e podem ser exibidos. A quantidade de caracteres separados que podem ser visualizados depende da RAM que tiver. Se tiver apenas 1 byte de RAM então pode mostrar apenas um caracter, se tiver 1GB de RAM, pode mostrar bem 1024*1024*1024 caracteres(Demasiado preguiçoso para fazer as contas).

Esta limitação no entanto aplica-se aos cálculos, no entanto acho que está interessado no padrão IPV4. Embora não esteja totalmente relacionada com os bit-size dos computadores, de alguma forma afectou as normas. Quando o padrão IPV4 foi criado, eles armazenaram os valores ip em inteiros de 32 bits. Agora, uma vez dado o tamanho, e tornou-se standard. Tudo o que sabemos sobre Internet estava dependente disso, e depois ficámos sem endereços IP para atribuir. Assim, se o padrão IP foi revisto para ter 64 bits, tudo deixará de funcionar, incluindo o seu router (assumo que isto esteja correcto) e outros dispositivos de rede. Portanto, tem de ser criada uma nova norma, que apenas trocou o inteiro de 32 bits por um de 128 bits. E o resto do padrão foi ajustado. O fabricante de hardware só precisa de declarar que suporta este novo padrão e ele ficará viral. Embora não seja assim tão simples, mas suponho que já percebeu o ponto aqui.

Disclaimer: A maioria dos pontos aqui mencionados são fiéis à minha suposição. Talvez eu tenha perdido pontos importantes aqui para tornar isto mais simples. Não sou bom com números, por isso devo ter falhado alguns dígitos, mas o meu ponto aqui é responder à resposta do PO sobre a razão pela qual não vai falhar o PC.

13
13
13
2014-01-08 11:27:08 +0000

Nos processadores, há “palavras”. Há palavras diferentes. Quando as pessoas dizem “processador de 32 bits”, significam sobretudo “largura do bus de memória”. Esta palavra consiste em diferentes “campos”, que se referem a subsistemas de computador correspondentes à transmissão (24 bits) e ao controlo (outros bits). Posso estar errado sobre números exactos, certifique-se através de manuais.

Aspecto completamente diferente é o cálculo. Os conjuntos de instruções SSE e MMX podem armazenar números inteiros longos. O comprimento máximo sem perda de produtividade depende da versão actual do SSE, mas é sempre sobre múltiplos de 64bits.

Os processadores Opteron actuais conseguem lidar com números de 256 bit de largura (não tenho a certeza sobre números inteiros, mas float é certo).

Sumário : (1) a largura do bus não está ligada directamente à largura de cálculo, (2) mesmo palavras diferentes (palavra memória, palavra registo, palavra bus, etc.) não estão ligadas umas às outras, outras têm divisor comum cerca de 8 ou 16 ou 24. Muitos processadores até usaram palavras de 6 bits (mas o seu histórico).

10
10
10
2014-01-08 20:39:13 +0000

O objectivo de um dispositivo informático, em geral, é aceitar, processar, armazenar e emitir dados. O hardware subjacente é apenas uma máquina que ajuda a desempenhar essas quatro funções. Não pode fazer nenhuma delas sem software.

O software é o código que diz à máquina como aceitar dados, como processá-los, como armazená-los e como fornecê-los a outros.

O hardware subjacente terá sempre limitações. No caso de uma máquina de 32 bits, a maioria dos registos que processam dados tem apenas 32 bits de largura. Isto não significa, no entanto, que a máquina não consiga lidar com números para além de 2^32, significa que se quiser lidar com números maiores, pode levar a máquina mais do que um ciclo para a aceitar, processar, armazenar ou emitir.

O software diz à máquina como lidar com números. Se o software for concebido para lidar com números grandes, envia uma série de instruções à CPU que lhe dizem como lidar com os números maiores. Por exemplo, o seu número pode ser representado por dois registos de 32 bits. Se quiser adicionar 1.234 ao seu número, o software diz ao CPU para adicionar primeiro 1.234 ao registo inferior, depois verifique o bit de overflow para ver se essa adição resultou num número demasiado grande para o registo inferior. Se o fez, então adiciona 1 ao registo superior.

Da mesma forma que as crianças do ensino básico são ensinadas a adicionar com porte, o CPU pode ser avisado para lidar com números maiores do que os que pode manter num único registo. Isto é verdade para a maioria das operações matemáticas genéricas, para números de qualquer dimensão prática.

8
8
8
2014-01-09 15:18:54 +0000

Os computadores de 32 bits só podem armazenar números até 2^32 numa única palavra máquina, mas isso não significa que não possam lidar com entidades maiores de dados.

O significado de um computador de 32 bits é geralmente que o bus de dados e o bus de endereços tem 32 bits de largura, o que significa que o computador pode lidar com 4 GB de espaço de endereços de memória de uma só vez, e enviar quatro bytes de dados de cada vez através do bus de dados.

No entanto, isso não limita o computador de tratar mais dados, apenas tem de dividir os dados em quatro pedaços de bytes quando é enviado através do barramento de dados.

O processador Intel normal de 32 bits pode tratar internamente números de 128 bits, o que lhe permitiria tratar números como 100000000000000000000000000000000000000 sem qualquer problema.

Pode lidar com números muito maiores do que os de um computador, mas depois os cálculos têm de ser feitos por software, o CPU não tem instruções para lidar com números maiores do que 128 bits. (Pode lidar com números muito maiores sob a forma de números de ponto flutuante, mas depois só tem 15 dígitos de precisão).

6
6
6
2014-01-10 19:11:43 +0000

Basta adicionar uma nota às muitas outras respostas, porque este é um facto muito importante nesta pergunta que tem sido esquecida.

“32 bit” refere-se à largura do endereço de memória. Não tem nada a ver com o tamanho do registo. Muitas CPUs de 32 bits têm provavelmente registos de 64 ou mesmo 128 bits. Referindo-se em particular à linha de produtos x86, as CPU de consumo recente, todas de 64 bits, possuem até 256 bit de registos para fins especiais.

Esta diferença entre a largura de registo e a largura de endereço existe desde os tempos antigos, quando tínhamos registos de 4 bits e endereços de 8 bits, ou vice-versa.

É simples ver que armazenar um grande número não é problema independentemente do tamanho do registo, como explicado noutras respostas.

A razão pela qual os registos, seja qual for o seu tamanho, também podem ser calculados com números maiores, é que os cálculos demasiado grandes podem ser decompostos em vários mais pequenos que cabem nos registos (é apenas um pouco mais complicado na realidade).

6
6
6
2014-01-10 21:36:01 +0000

As respostas já dadas são, na verdade, bastante boas, mas tendem a abordar a questão de diferentes lados e, por conseguinte, apresentam uma imagem incompleta. São também um pouco técnicas demais, na minha opinião.

Por isso, só para esclarecer algo que é sugerido mas não explicitamente expresso em nenhuma das outras respostas, e que penso ser o cerne da questão:

** Está a misturar vários conceitos na sua pergunta** , e um deles (“32 bit”) pode na verdade referir-se a uma variedade de coisas diferentes (e respostas diferentes têm assumido interpretações diferentes). Todos estes conceitos têm algo a ver com o número de bits (1’s e 0’s) utilizados (ou disponíveis) em vários contextos computacionais (o que quero dizer com isto será clarificado pelos exemplos abaixo), mas os conceitos são outros não relacionados.

Explicitamente:

  • “IPv4/6” refere-se a protocolo internet , um conjunto de regras que definem como a informação deve ser empacotada e interpretada na internet. A distinção primária (ou pelo menos a mais conhecida) entre IPv4 e IPv6 é que o espaço de endereços (ou seja, o conjunto de endereços que pode ser utilizado para distinguir entre diferentes localizações na rede) é maior no IPv6. Isto tem a ver com o número de bits em cada pacote de dados enviados através da rede que são alocados para (ou seja, reservados para efeitos de) identificação do remetente do pacote e do destinatário pretendido.
  • Analogia não-computadora: Cada pacote é como uma carta enviada via snail-mail, e o espaço de endereçamento é como a quantidade de caracteres que é “permitido” utilizar ao escrever o endereço e o endereço de retorno no envelope.
  • Não vejo isto mencionado em nenhuma das outras respostas até agora.
  • As “palavras” da memória do computador (32-bit e 64-bit) podem geralmente ser pensadas como a menor parte dos dados que um computador utiliza, ou “pensa” em. Estes bits de dados juntam-se para compor outros bits de dados, tais como pedaços de texto ou inteiros maiores.
  • Analogia não computacional: as palavras podem ser pensadas como letras que compõem palavras em papel, ou mesmo como palavras individuais num comboio de pensamento.
  • Ver Guffa’s answer , sanaris’s answer , e o primeiro parágrafo da resposta de gronostaj .
  • 32-bit pointers podem ou não ser palavras, mas são contudo tratadas atomicamente (ou seja, como unidades individuais que não podem ser decompostas em componentes mais pequenos). Os apontadores são o nível mais baixo em que um computador pode gravar a localização na memória de algum pedaço arbitrário de dados. Note que o tamanho do ponteiro utilizado pelo computador (ou, na realidade, pelo sistema operativo) limita o alcance da memória que pode ser acedida por um único ponteiro, uma vez que existem apenas tantas localizações de memória possíveis para as quais um ponteiro pode “apontar” como existem valores possíveis para o próprio ponteiro. Isto é análogo à forma como o IPv4 limita a gama de endereços Internet possíveis, mas não limita a quantidade de dados que podem estar presentes, por exemplo, numa determinada página Web. No entanto, o tamanho do ponteiro não limita o tamanho dos próprios dados para os quais o próprio ponteiro pode apontar. (Para um exemplo de um esquema para permitir que o tamanho dos dados ultrapasse o intervalo do ponteiro, veja o Linux inode pointer structure . Note que este é um uso ligeiramente diferente da palavra “ponteiro” do que é típico, uma vez que o ponteiro normalmente se refere a um ponteiro em memória de acesso aleatório, não espaço no disco rígido)
  • analogia não computacional: hmmmm…..este é um pouco complicado. Talvez o sistema decimal Dewey para indexação de materiais de biblioteca seja um pouco semelhante? Ou qualquer sistema de indexação, realmente.
  • Veja SiteNook’s answer .
  • Por favor note que a minha explicação dos apontadores acima elide alguns detalhes subtis e não é, sem dúvida, totalmente correcta. Contudo, em linguagens de programação em que os programadores trabalham directamente com apontadores, o modo mental que desenhei é normalmente suficiente para fins práticos.
  • Os números que um computador é “capaz de mostrar ” não são (para fins práticos) limitados pelo hardware ou sistema operativo do computador; eles são tratados como qualquer outro texto.
  • Analogia não informática: escrever numa folha de papel
  • Ver resposta do utilizador1306322 e resposta do Bigbio2002

Note-se que esta não pretende ser uma lista exaustiva de interpretações para a frase “32 bits”.

Crédito extra: para ver realmente a distinção filosófica entre números e pedaços primitivos de memória de computador, leia um pouco sobre Turing machines .

5
5
5
2014-01-11 23:24:10 +0000

Na sua mente, só conhece 10 dígitos diferentes. 0 a 9. Internamente no seu cérebro, isto é certamente codificado de forma diferente do que num computador.

Um computador usa bits para codificar números, mas isso não é importante. Essa é apenas a forma que os engenheiros escolheram para codificar as coisas, mas você deve ignorar isso. Pode pensar nisso como um computador de 32 bits tem uma representação única de mais de 4 mil milhões de valores diferentes, enquanto nós, humanos, temos uma representação única para 10 valores diferentes.

Sempre que temos de compreender um número maior, usamos um sistema. O número mais à esquerda é o mais importante. É 10 vezes mais importante que o próximo.

Um computador capaz de diferenciar entre quatro mil milhões de valores diferentes, terá igualmente de fazer com que o valor mais à esquerda, num conjunto de valores, seja quatro mil milhões de vezes mais importante que o próximo valor desse conjunto. Na verdade, um computador não se importa de todo. Não atribui “importância” aos números. Os programadores têm de fazer um código especial para tratar disso.

Sempre que um valor se torna superior ao número de símbolos únicos, 9 numa mente humana, adiciona-se um ao número à esquerda.

3+3=6

Neste caso, o número ainda cabe dentro de um único “slot”

5+5=10. This situation is called an overflow.

Assim, os humanos lidam sempre com o problema de não terem símbolos únicos suficientes. A menos que o computador tenha um sistema para lidar com isso, ele simplesmente escreveria 0, esquecendo que havia um número extra. Felizmente, os computadores têm uma “bandeira de transbordo” que é levantada neste caso.

987+321 is more difficult.

Talvez tenha aprendido um método na escola. Um algoritmo. O algoritmo é bastante simples. Comece por adicionar os dois símbolos mais à esquerda.

7+1=8, we now have ...8 as the result so far

Depois passa para a ranhura seguinte e executa a mesma adição.

8+2=10, the overflow flag is raised. We now have ...08, plus overflow.

Como tivemos um “overflow”, significa que temos de adicionar 1 ao número seguinte.

9+3=12, and then we add one due to overflow. ...308, and we had another overflow.

Não há mais números a adicionar, por isso simplesmente criamos uma ranhura e inserimos 1 porque a bandeira de “overflow” foi levantada.

1308

Um computador faz exactamente da mesma forma, excepto que tem 2^32 ou ainda melhor 2^64 símbolos diferentes, em vez de apenas 10 como os humanos.

A nível de hardware, o computador funciona em bits simples usando exactamente o mesmo método. Felizmente, isso é abstraído para os programadores. Os bits são apenas dois dígitos, porque isso é fácil de representar numa linha de alimentação. Ou a luz está ligada, ou está apagada.

Finalmente, um computador pode mostrar qualquer número como uma simples sequência de caracteres. É nisso que os computadores são melhores. O algoritmo de conversão entre uma sequência de caracteres e uma representação interna é bastante complexo.

5
5
5
2014-01-11 17:59:58 +0000

No caso de querer um exemplo prático de quantos programas num sistema Linux típico lidam com processamento e saída de grande número:

libgmp - A Biblioteca Aritmética de Múltipla Precisão GNU é a biblioteca mais utilizada para este fim nos sistemas Linux. Um exemplo simples de multiplicação de 2^80 por 1000:

#include <gmp.h>

// Each large integer uses the mpz_t type provided by libgmp
mpz_t a_large_number;
mpz_t base;
mpz_t result;

// Initalize each variable
mpz_init(a_large_number);
mpz_init(base);
mpz_init(result);

// Assign the number 2 to the variable |base|
mpz_set_ui(base, 2);

// Raise base^80 (2^80), store the result in |a_large_number|
mpz_pow_ui(a_large_number, base, 80);

// Multiply |a_large_number| by 1000, store the result in |result|
mpz_mul_ui(result, a_large_number, 1000);

// Finally, output the result in decimal and hex notation
gmp_printf("decimal: %Zd, hex: %ZX\n", result, result);

Então basicamente é o mesmo que usar os operadores normais + - * / operadores, apenas com uma biblioteca para quebrar os números e armazená-los internamente como números de múltiplas palavras de máquinas (i.e. 32-bit). Há também funções do tipo scanf() para lidar com a conversão de entrada de texto para tipos inteiros.

A estrutura do mpz_t é exatamente como o exemplo de Scott Chamberlain de contar até 6 usando duas mãos. É basicamente um conjunto de tipos de mp_limb_t, e quando um número é demasiado grande para caber numa palavra de máquina, a GMP usa múltiplos mp_limb_t para armazenar as partes alta/baixa do número.

5
5
5
2014-01-09 16:36:20 +0000

Se escrever 1000000000000, por exemplo, em calculadora, o computador irá calculá-lo como tipo real com ponto decimal. O limite para 32 bits que mencionou toca mais em todos os *números de tipo de integer** sem ponto decimal. Diferentes tipos de dados utilizam métodos diferentes para entrar em bits/bytes.

Números de tipo de integer* : Esta tabela pode ajudá-lo a apanhar o ponto http://msdn.microsoft.com/en-us/library/296az74e.aspx ). Isto toca nos limites de C++. Por exemplo Int64 type number* tem limites de -9223372036854775808 a 9223372036854775807.

Números de tipo reais* : Os números de tipo reais contêm valor com ponto flutuante e exponente* e pode introduzir números muito maiores, mas com precisão/precisão limitada. http://msdn.microsoft.com/en-us/library/6bs3y5ya.aspx ) Por exemplo LDBL (duplo grande) em C++ tem um expoente máximo de 308, então possivelmente você pode entrar ou ter como resultado número 9.999 x 10^308, significa que você terá teoricamente 308(+1) dígitos de 9 mas apenas 15 dígitos mais importantes serão usados para representá-lo, o resto será perdido, causa de precisão limitada.

Adicionalmente, existem diferentes linguagens de programação e elas podem ter diferentes implementações de limites de números. Assim, pode imaginar que aplicações especializadas poderiam lidar com números muito maiores (e/ou mais exactos/precisos) do que C++.

3
3
3
2014-01-12 00:41:20 +0000

Porque não está a exibir um número (no que diz respeito ao computador), mas um string , ou uma sequência de dígitos. Claro, algumas aplicações (como a calculadora, acho eu), que lidam com números, podem lidar com um número desses, acho eu. Eu não sei que truques eles usam… Tenho a certeza que algumas das outras respostas, mais elaboradas, cobrem isso.

0
0
0
2016-12-30 11:54:31 +0000

A maior parte do conteúdo desta resposta provinha originalmente de esta resposta (escrita antes dessa outra pergunta foi marcada como um duplicado). Então discuto a utilização de valores de 8 bits (apesar desta pergunta ser feita sobre valores de 32 bits), mas não faz mal porque os valores de 8 bits são mais simples de compreender conceptualmente, e os mesmos conceitos aplicam-se a valores maiores como a aritmética de 32 bits.

Quando se adicionam dois números que são de 8 bits, o maior número que se pode obter (0xFF + 0xFF = 1FE). De facto, se multiplicar dois números que são 8 bits, o maior número que consegue obter (0xFF * 0xFF = 0xFE01) é ainda 16 bits, duas vezes de 8 bits.

Agora, pode estar a assumir que um processador x-bit só consegue manter um registo de x bits. (Por exemplo, um processador de 8 bits só pode controlar 8 bits.) Isso não é exacto. O processador de 8 bits recebe dados em pedaços de 8 bits. (Estes “pedaços” têm normalmente um termo formal: uma “palavra”. Num processador de 8 bits, são utilizadas palavras de 8 bits. Num processador de 64 bits, podem ser utilizadas palavras de 64 bits)

Byte #1: a instrução MUL Byte #2: os bytes de ordem elevada (por exemplo, 0xA5) Byte #3: os bytes de ordem inferior (por exemplo, 0xCB) O computador pode gerar um resultado que é superior a 8 bits. O CPU pode gerar resultados como este: 0100 0000 0100 0010 xxxx xxxx xxxx xxxx xxxx 1101 0111 a.k.a.: 0x4082xxxxxxD7 Agora, deixe-me interpretar que para si: 0x significa apenas que os seguintes dígitos são hexadecimais.
Discutirei o “40” em mais pormenor momentaneamente. 82 faz parte do registo “A”, que é uma série de 8 bits. xx e xx fazem parte de dois outros registos, denominados registo “B” e registo “C”. A razão pela qual não enchi esses bits com zeros ou uns é que uma instrução “ADD” (enviada para o CPU) pode resultar em que esses bits não sejam alterados pela instrução (enquanto a maioria dos outros bits que uso neste exemplo podem ser alterados, excepto alguns dos bits de bandeira). D7 caberiam em mais bits, chamado registo “D”. Um registo é apenas um pedaço de memória. Os registos são incorporados nas CPUs, para que a CPU possa aceder aos registos sem precisar de interagir com a memória num stick RAM.

Então o resultado matemático de 0xA5 vezes 0xCB é 0x82D7.

Agora, porque é que os bits foram divididos nos registos A e D em vez dos registos A e B, ou nos registos C e D? Bem, mais uma vez, este é um cenário de amostra que estou a utilizar, destinado a ser bastante semelhante em conceito a uma verdadeira linguagem Assembly (Intel x86 16 bits, tal como utilizado pelos Intel 8080 e 8088 e por muitas CPUs mais recentes). Pode haver algumas regras comuns, tais como o registo “C” ser tipicamente utilizado como um índice para operações de contagem (típico para loops), e o registo “B” ser utilizado para manter o registo de offsets que ajudam a especificar a localização da memória. Assim, “A” e “D” podem ser mais comuns para algumas das funções aritméticas comuns.

Cada instrução de CPU deve ter alguma documentação, utilizada por pessoas que programam em Assembly. Essa documentação deve especificar quais os registos que são utilizados por cada instrução. (Assim, a escolha dos registos a utilizar é frequentemente especificada pelos designers da CPU, não pelos programadores da linguagem Assembly. Embora possa haver alguma flexibilidade)

Agora, voltando ao “40” no exemplo acima: isto é uma série de bits, muitas vezes chamados de “registo de bandeiras”. Cada bit no registo de bandeiras tem um nome. Por exemplo, existe um bit de “overflow” que a CPU pode definir se o resultado for maior que o espaço que pode armazenar um byte dos resultados. (O bit “overflow” pode ser frequentemente referido pelo nome abreviado de “OF”. Isso é um o maiúsculo, não um zero). O software pode verificar o valor desta bandeira e reparar no “problema”. Trabalhar com este bit é muitas vezes tratado invisivelmente por linguagens de nível superior, por isso os programadores principiantes muitas vezes não aprendem como interagir com as bandeiras da CPU. No entanto, os programadores Assembly podem normalmente aceder a algumas destas flags de uma forma muito semelhante a outras variáveis.

Por exemplo, pode ter múltiplas instruções ADD. Uma instrução ADD pode armazenar 16 bits de resultados no registo A e o registo D, enquanto outra instrução pode apenas armazenar os 8 bits baixos no registo A, ignorar o registo D, e especificar o bit de sobrecarga. Depois, mais tarde (após armazenar os resultados do registo A na RAM principal), poderá utilizar outra instrução ADD que armazena apenas os 8 bits altos num registo (possivelmente o registo A.) Se necessitará de utilizar uma bandeira de sobrecarga pode depender da instrução de multiplicação que utiliza.

(Também existe normalmente uma flag de “overflow”, caso subtraia demasiado para caber no resultado desejado)

Só para lhe mostrar como as coisas ficaram complicadas: O Intel 4004 era um CPU de 4 bits O Intel 8008 era um CPU de 8 bits. Tinha registos de 8 bits chamados A, B, C, e D. O Intel 8086 era um CPU de 16 bits. Tinha registos de 16 bits denominados AX, BX, CX, e DX. A Intel 80386 era uma CPU de 32 bits. Tinha registos de 32 bits denominados EAX, EBX, ECX e EDX. As CPUs Intel x64 têm registos de 64 bits denominados RAX, RBX, RCX e RDX. Os chips x64 podem executar código de 16 bits (em alguns modos de operação), e podem interpretar instruções de 16 bits. Ao fazê-lo, os bits que constituem o registo AX são metade dos bits que constituem o registo EAX, que são metade dos bits que constituem o registo RAX. Assim, sempre que se altera o valor do AX, também se altera a EAX e o RAX, porque os bits utilizados pelo AX fazem parte dos bits utilizados pelo RAX. (Se você alterar EAX por um valor que é um múltiplo de 65.536, então os baixos 16 bits são inalterados para que AX não mude. Se alterar EAX por um valor que não seja um múltiplo de 65.536, então isso afectaria AX também.)

Existem mais bandeiras e registos do que apenas os que mencionei. Eu simplesmente escolhi algumas das mais usadas para dar um exemplo conceptual simples.

Agora, se estiver num CPU de 8 bits, quando escreve na memória, pode encontrar algumas restrições sobre poder referir-se a um endereço de 8 bits, e não a um endereço de 4 bits ou 16 bits. Os detalhes irão variar com base na CPU, mas se tiver tais restrições, então a CPU pode estar a lidar com palavras de 8 bits, razão pela qual a CPU é mais comummente referida como uma “CPU de 8 bits”.