Questão Se as máquinas de 32 bits só puderem manipular números de até 2 ^ 32, por que posso gravar 1000000000000 (trilhões) sem que minha máquina falhe?


Computadores de 32 bits só podem armazenar números inteiros assinados até 231 - 1
É por isso que ficamos sem endereços IPv4 e entramos na era de 64 bits.

No entanto, o número 231 - 1 (2.147.483.647) não é tão grande quanto o número 1 trilhão (1.000.000.000.000) que eu pareço ser capaz de exibir bem sem que minha máquina caia.

Alguém pode explicar por que isso é?


365


origem


A questão é falha. Máquinas de 32 bits podem manipular números muito maiores que 2 ^ 32. Eles fazem isso o tempo todo, com "longo" e assim por diante. Eles só podem armazenar até 2 ^ 32 em um registro, mas o software é gravado para contornar esse problema. Algumas linguagens modernas nem sequer têm problemas com o tamanho de um determinado número. - JFA
Por favor, mantenha os comentários no tópico, educados e relevantes para os aspectos técnicos da questão. Quase 50 comentários de piadas já tiveram que ser removidos e gostaríamos de evitar bloquear a postagem. Obrigado. - nhinkle♦
Esta questão foi escrita de uma forma que é um pouco desleixada. O que você quer dizer com "escrever" e "exibir" o número 1000000000000? Quando você escreveu a pergunta que você escreveu o número 1000000000000, e seu navegador da Web exibe muito bem, eu suponho, mas isso não deve ser nada estranho para alguém que já usou um computador antes. A questão pede interpretação livre. - HelloGoodbye
A consciência humana é estimada em cerca de 50 bits (eu li em algum lugar). Então a questão não é "Como eu posso escrever 10^9 sem o meu PC cair? "mas sim" Como posso escrever 10^(18) sem meu cérebro batendo? - Hagen von Eitzen
Computadores de 32 bits só podem armazenar inteiros UNSIGNED até 2 ^ 32 - 1. 2 ^ 32 - 1 não é igual a 2.147.483.647 ... 300 votos acima e ninguém percebeu isso? - Koray Tugay


Respostas:


Eu respondo a sua pergunta perguntando-lhe uma diferente:

Como você conta com os dedos para 6?

Você provavelmente conta até o maior número possível com uma mão e depois passa para a segunda quando não tem mais dedos. Os computadores fazem a mesma coisa, se precisarem representar um valor maior do que um único registrador pode reter, eles usarão vários blocos de 32 bits para trabalhar com os dados.


785



Engraçado, @codename. Como então você conta com seus dedos para 32 ou mais (ou seja, uma vez que 2 ^ 5 está esgotado)? ;) A analogia de se mover para a outra mão é boa ... mesmo se o binário atrasa a necessidade de se mover para a outra mão. O que eu gostaria de ver está contando até 1.024 ou mais com a destreza pedial para mover-se para os dedos dos pés para contar mais em binário - até 1.048.575! :) Isso é potencialmente 20-bits de poder da placa-filha. : P - J0e3gan
Por favor, mantenha os comentários no tópico e relevantes para discutir os aspectos técnicos desta resposta. Mais de 60 comentários de piadas já foram excluídos desta resposta, e gostaríamos de evitar o bloqueio da postagem. - nhinkle♦
@ codename- easy, você atribui um dedo como um ponteiro de pilha. Depois de ficar sem dedos, adicione a quantia à pilha e reinicie a contagem. - Makach
Onde você aprendeu isso, @codename? Eu ouvi isto primeiro de Frederik Pohl, veja e. Aqui hjkeen.net/halqn/f_pohl3.htm - Zane
Eu acho que esta não é a resposta para a questão relevante. Resposta por @ Bigbio2002 é o correto. Aqui "1000000000000" não é um número, mas um texto, assim como "adsfjhekgnoregrebgoregnkevnregj". O que você está dizendo é verdade, mas eu sinto fortemente que esta não é a resposta correta. E para ver tantos votos positivos ... - Master Chief


Você está correto que um inteiro de 32 bits não pode conter um valor maior que 2 ^ 32-1. No entanto, o valor desse inteiro de 32 bits e como ele aparece na tela é duas coisas completamente diferentes. A cadeia de caracteres impressa "1000000000000" não é representada por um inteiro de 32 bits na memória.

Para exibir literalmente o número "1000000000000" requer 13 bytes de memória. Cada byte individual pode conter um valor de até 255. Nenhum deles pode conter o valor numérico inteiro, mas interpretado individualmente como caracteres ASCII (por exemplo, o caractere '0'é representado pelo valor decimal 48, valor binário 00110000), eles podem ser agrupados em um formato que faça sentido para você, um ser humano.


Um conceito relacionado em programação é typecasting, que é como um computador irá interpretar um fluxo particular de 0areia 1s. Como no exemplo acima, ele pode ser interpretado como um valor numérico, um caractere ou até mesmo algo totalmente diferente. Enquanto um inteiro de 32 bits pode não ser capaz de manter um valor de 1000000000000, um número de ponto flutuante de 32 bits será capaz de, usando uma interpretação totalmente diferente.

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


397



Na verdade isso é mais correto, mas não é bem assim. É improvável que um número de ponto flutuante de 32 pontos represente precisamente 1000000000000. Ele representará um número muito próximo do número desejado, mas não exatamente dele. - Tim B
@TimB: Você já ouviu falar sobre o formato decimal32? Faz parte do padrão IEEE 754-2008. Este formato é capaz de representar corretamente este número :) - V-X
É verdade que isso pode. No entanto, esse não é o formato que as pessoas querem dizer quando dizem "float", que geralmente se refere a um número de ponto flutuante de 32 bits conforme armazenado e usado por processadores de ponto flutuante padrão nos computadores atuais. - Tim B
@TimB de fato. O número mais próximo daquele que pode ser representado como um float32 é 999999995904 - greggo
@TimB: Mas um número de ponto flutuante de 64 bits pode representar facilmente 1000000000000 exatamente. São 10 ^ 12 ou 2 ^ 12 * 5 ^ 12; 5 ^ 12 requer 28 bits de mantissa. - Keith Thompson


Em primeiro lugar, os computadores de 32 bits podem armazenar números de até 2³²-1 em uma única palavra de máquina. Palavra máquina é a quantidade de dados que a CPU pode processar de maneira natural (ou seja, operações em dados desse tamanho são implementadas em hardware e geralmente são mais rápidas de serem executadas). As CPUs de 32 bits usam palavras que consistem em 32 bits, portanto, podem armazenar números de 0 a 2³²-1 em uma palavra.

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

  • 1 trilhão é um conceito abstrato de número
  • 1000000000000 é texto

Pressionando 1 uma vez e depois 0 12 vezes você está digitando texto. 1 insumos 1, 0 insumos 0. Vejo? Você está digitando caracteres. Personagens não são números. As máquinas de escrever não tinham CPU ou memória e estavam lidando muito bem com "números", porque é apenas texto.

Prova que 1000000000000 não é um número, mas texto: pode significar 1 trilhão (em decimal), 4096 (em binário) ou 281474976710656 (em hexadecimal). Tem ainda mais significados em diferentes sistemas. Significado de 1000000000000 é um número e armazená-lo é uma história diferente (vamos voltar a ele daqui a pouco).

Para armazenar o texto (na programação é chamado corda) 1000000000000 você precisa de 14 bytes (um para cada caractere mais um byte NULL de terminação que basicamente significa "a string termina aqui"). São 4 palavras de máquina. 3 e metade seriam suficientes, mas, como eu disse, as operações em palavras de máquina são mais rápidas. Vamos assumir ASCII é usado para armazenamento de texto, portanto, na memória, ele ficará assim: (convertendo códigos ASCII correspondentes a 0 e 1 para binário, cada palavra em uma linha separada)

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

Quatro caracteres se encaixam em uma palavra, o resto é movido para o próximo. O resto é movido para a próxima palavra até que tudo (incluindo o primeiro byte NULL) caiba.

Agora, de volta ao armazenamento de números. Funciona exatamente como com texto transbordante, mas eles são ajustados da direita para a esquerda. Pode parecer complicado, então aqui está um exemplo. Por uma questão de simplicidade, vamos supor que:

  • 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

Observe que os dois operandos caberiam em um byte, mas não no resultado. Mas nós temos outro pronto para usar. Agora vamos armazenar 99:

9 9
0 0

Novamente, usamos o segundo byte para armazenar o número. Vamos adicionar 1:

0 0
0 0

Ops ... Isso é chamado estouro de inteiro e é uma causa de muitos problemas sérios, às vezes muito caros.

Mas se esperamos que esse estouro aconteça, podemos fazer isso:

0 0
9 9

E agora adicione 1:

0 1
0 0

Se torna mais claro se você remover espaços e novas linhas de separação de bytes:

0099    | +1
0100

Nós previmos que o estouro pode acontecer e podemos precisar de memória adicional. O manuseio de números dessa maneira não é tão rápido quanto os números que se encaixam em palavras isoladas e devem ser implementados no software. Adicionar suporte a números de duas palavras de 32 bits a uma CPU de 32 bits efetivamente torna uma CPU de 64 bits (agora ela pode operar em números de 64 bits nativamente, certo?).

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

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

Converter esses números em um sistema decimal é complicado, no entanto. (mas funciona muito bem com hexadecimal)


189



Sua resposta é bastante condescendente. OP está claramente falando sobre o número, não o texto: large as the number 1 trillion (1000000000000). Além disso, você está quase falando Aritmética de precisão arbitrária, mas você nunca menciona nenhum dos termos para o que está dizendo ... - MirroredFate
"1 trilhão" também é uma string - Elzo Valugi
@ElzoValugi É. Eu tive que encontrar alguma maneira de apresentar o conceito de número abstrato, em oposição a string representando um número. Eu acredito que "1 trilhão" é uma maneira melhor e menos ambígua de fazê-lo (veja a prova na resposta). - gronostaj
@MirroredFate Eu discordo de 'está claramente falando sobre o número'. OP diz "exibido bem", que claramente é falando sobre o texto '1000000000000' para mim ... - Joe
@yannbane 'A' é um personagem e não um número. '? é um personagem e não um número. '1' é um personagem e não um número também. Personagens são apenas símbolos. Eles podem representar dígitos ou números, mas definitivamente não são números. '1' pode representar um, dez, cem, mil e assim por diante, é apenas um símbolo que representa um dígito que pode ser um número ou parte dele. '10' (string de caracteres) pode significar dois ou oito ou dez ou dezesseis, etc., mas quando você diz que tem dez maçãs, está usando um número dez e todo mundo sabe o que você quer dizer. Há uma enorme diferença entre personagens e números. - gronostaj


Você também é capaz de escrever "ESTA DECLARAÇÃO É FALSA" sem que o seu computador falhe :) @ A resposta de Scott é precisa para certas estruturas de cálculo, mas a sua questão de "escrever" um grande número implica que é apenas texto simples, pelo menos até ser interpretado.

Editar: agora com menos sarcasmo mais informações úteis sobre diferentes maneiras um número pode ser armazenado na memória. Eu vou estar descrevendo estes com maior abstração isto é, em termos que um programador moderno pode escrever código antes de ser traduzido para código de máquina para execução.

Os dados em um computador devem ser restritos a um certo tipoe uma definição de computador desse tipo descreve quais operações podem ser executadas nesses dados e como (ou seja, comparar números, concatenar texto ou XOR como booleano). Você não pode simplesmente adicionar texto a um número, assim como não é possível multiplicar um número por texto, para que alguns desses valores possam ser convertidos entre os tipos.

Vamos começar com inteiros sem sinal. Nesses tipos de valor, todos os bits são usados ​​para armazenar informações sobre dígitos; o seu é um exemplo de Número inteiro sem sinal de 32 bits onde qualquer valor de 0 para 2^32-1 pode ser armazenado. E sim, dependendo da linguagem ou arquitetura da plataforma usada, você poderia ter inteiros de 16 bits ou inteiros de 256 bits.

E se você quiser ficar negativo? Intuitivamente números inteiros assinados é o nome do jogo. Convenção é alocar todos os valores de -2^(n-1) para 2^(n-1)-1 - desta forma evitamos a confusão de ter que lidar com duas maneiras de escrever +0 e -0. Portanto, um inteiro assinado de 32 bits manteria um valor de -2147483648 para 2147483647. Legal, não é?

Ok, nós cobrimos inteiros que são números sem um componente decimal. Expressar isso é mais complicado: a parte não-inteira pode sensatamente estar em algum lugar entre 0 e 1, então cada bit extra usado para descrevê-lo aumentaria sua precisão: 1/2, 1/4, 1/8 ... O problema é que você não pode expressar precisamente um decimal simples 0.1 como uma soma de frações que só podem ter poderes de dois em seu denominador! Não seria muito mais fácil armazenar o número como um número inteiro, mas concordar em colocar o ponto radix (decimal) no lugar? Isso é chamado ponto fixo números, onde nós armazenamos 1234100 mas concordar com uma convenção para lê-lo como 1234.100 em vez de.

Um tipo relativamente mais comum usado para cálculos é floating point. O modo como funciona é realmente puro, usa um bit para armazenar o valor do sinal e, em seguida, alguns para armazenar o expoente e o significando. Existem padrões que definem tais alocações, mas para um Flutuador de 32 bits o número máximo que você seria capaz de armazenar é uma esmagadora

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

Isso, no entanto, vem com o custo de precisão. O JavaScript disponível nos navegadores usa floats de 64 bits e ainda não consegue acertar as coisas. Basta copiar isso na barra de endereços e pressionar enter. Alerta de spoiler: o resultado é não será 0.3.

javascript:alert(0.1+0.2);

Existem mais tipos alternativos, como o Microsoft .NET 4.5 BigInteger, que teoricamente não tem limites superiores ou inferiores e deve ser calculado em "lotes"; mas talvez as tecnologias mais fascinantes sejam aquelas que Compreendo matemática, como o motor Wolfram Mathematica, que pode trabalhar precisamente com valores abstratos como infinidade.


40



Você pode fazer isso em esta realidade. Tente fazer isso no universo de Star Trek. Apenas recue antes, por causa de todas as faíscas e fumaça. - Michael Petrotta
Isso não é exatamente como funciona o ponto fixo. Na verdade, é um sistema em que os números são dimensionados e tendenciosos para produzir o ponto decimal. No seu exemplo, a escala é 1/1000, mas também há números de ponto fixo (especialmente em computação gráfica) como este: 0 = 0,0, 255 = 1,0 - a escala é 1/255. - Andon M. Coleman


A chave é entender como os computadores codificar números.

É verdade que, se um computador insiste em armazenar números usando uma representação binária simples do número usando uma única palavra (4 bytes em um sistema de 32 bits), um computador de 32 bits só pode armazenar números até 2 ^ 32. Mas há muitas outras maneiras de codificar números, dependendo do que você deseja alcançar com eles.

Um exemplo é como os computadores armazenam números de ponto flutuante. Os computadores podem usar várias formas diferentes de codificá-los. O padrão IEEE 754 define regras para codificar números maiores que 2 ^ 32. Grosseiramente, os computadores podem implementar isso dividindo os 32 bits em partes diferentes representando alguns dígitos do número e outros bits representando o Tamanho do número (ou seja, o expoente, 10 ^ x). Isso permite um muito maior alcance de números em termos de tamanho, mas compromete a precisão (o que é aceitável para muitos propósitos). É claro que o computador também pode usar mais de uma palavra para essa codificação, aumentando a precisão da magnitude dos números codificados disponíveis. A versão decimal simples do padrão IEEE 32 permite números com cerca de 7 dígitos decimais de precisão e números de até 10 ^ 96 em magnitude.

Mas há muitas outras opções se você precisar de precisão extra. Obviamente, você pode usar mais palavras em sua codificação sem limite (embora com uma penalidade de desempenho para converter para dentro e fora do formato codificado). Se você quiser explorar uma maneira que isso pode ser feito, há um ótimo complemento de código aberto para o Excel que usa um esquema de codificação que permite centenas de dígitos de precisão no cálculo. 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 ótima maneira de aprender como os computadores alcançam a codificação de números maiores. E você pode brincar com os resultados dentro do Excel sem precisar instalar nenhuma ferramenta de programação.


31





Está tudo na sua pergunta.

Você pode Escreva qualquer número que você goste no papel. Tente escrever um trilhão de pontos em uma folha branca de papel. É lento e ineficaz. É por isso que temos um sistema de 10 dígitos para representar esses grandes números. Nós até temos nomes para grandes números como "milhões", "trilhões" e mais, então você não diz one one one one one one one one one one one... alto.

Os processadores de 32 bits são projetados para funcionar da maneira mais rápida e eficiente com blocos de memória com exatamente 32 dígitos binários. Mas nós, pessoas, comumente usamos sistema numérico de 10 dígitos, e os computadores, sendo eletrônicos, usam sistema de 2 dígitos (binário). Os números 32 e 64 são, por acaso, potências de 2. Assim, um milhão e um trilhão são potências de 10. É mais fácil para nós operarmos com esses números do que multidões de 65536, por exemplo.

Nós dividimos grandes números em dígitos quando os escrevemos no papel. Os computadores dividem os números em um número maior de dígitos. Podemos anotar qualquer número que quisermos, assim como os computadores, se os projetarmos assim.


24





32bit e 64bit referem-se a endereços de memória. A memória do seu computador é como caixas postais, cada uma com um endereço diferente. A CPU (Unidade Central de Processamento) usa esses endereços para endereçar locais de memória na sua RAM (Random Access Memory). Quando a CPU só conseguia lidar com endereços de 16 bits, você só podia usar 32 MB de RAM (o que parecia enorme na época). Com 32bit ele foi para 4 + gb (o que parecia enorme na época). Agora que temos endereços de 64 bits, a RAM vai para terabytes (o que parece ser enorme).
No entanto, o programa é capaz de alocar vários blocos de memória para coisas como armazenar números e texto, que depende do programa e não está relacionado ao tamanho de cada endereço. Assim, um programa pode informar a CPU, eu vou usar 10 blocos de endereços de armazenamento e, em seguida, armazenar um número muito grande, ou uma cadeia de 10 letras ou qualquer outra coisa.
Nota lateral: Os endereços de memória são apontados por "ponteiros", portanto, o valor de 32 e 64 bits significa o tamanho do ponteiro usado para acessar a memória.



15



Boa resposta, exceto para os detalhes - 16bits de espaço de endereço deu 64kb, não 32mb, e máquinas como as 286 tinham endereços de 24 bits (por 16mb). Além disso, com endereços de 64 bits, você vai além dos terabytes - mais como 16 exabytes - os terabytes estão em torno do tipo de limite que as placas-mãe / CPUs da geração atual estão impondo - não o tamanho dos endereços. - Phil
32 bits refere-se ao tamanho da palavra da máquina, não aos endereços de memória. Como Phil mencionou, 286 era uma CPU de 16 bits, mas usava 24 bits para endereçar a segmentação de memória. CPUs x86 são de 32 bits, mas usam endereçamento de 36 bits. Vejo PAE. - gronostaj
@gronostaj well x86 tem endereçamento de 32 bits do 386 para o Pentium. - Ruslan
Votado porque esta é a única resposta CORRETA aqui - 32bit refere-se ao endereçamento de memória de 32 bits, não à aritmética de 32 bits. - user1207217
@ user1207217: ?? Então, de acordo com o seu raciocínio, por exemplo, Z80 ou 8080 são processadores de 16 bits (por causa do endereçamento de memória de 16 bits e barramento de memória)? - pabouk


Porque exibir o número é feito usando caracteres individuais, não inteiros. Cada dígito no número é representado com um literal de caractere separado, cujo valor inteiro é definido pela codificação utilizada, por exemplo 'a' é representado com valor ascii 97, enquanto '1' é representado com 49. Verifica a mesa ascii aqui.
Para exibir tanto 'a' quanto '1' é o mesmo. Eles são literais de caracteres, não inteiros. Cada caracter literal pode ter valor máximo de 255 na plataforma de 32 bits armazenando o valor em 8 bits ou 1 byte (dependendo da plataforma, porém 8 bits é o tamanho de caractere mais comum), assim eles podem ser agrupados e podem ser exibido. Quantos caracteres separados eles podem exibir depende da RAM que você tem. Se você tem apenas 1 byte de RAM, então você pode exibir apenas um caractere, se você tiver 1 GB de RAM, você pode exibir bem 1024 * 1024 * 1024 caracteres (com preguiça de fazer as contas).

Essa limitação, no entanto, se aplica aos cálculos, mas acho que você está interessado no padrão IPV4. Embora não esteja totalmente relacionado com o bit-size, de alguma forma afetou os padrões. Quando o padrão IPV4 foi criado, eles armazenaram os valores de IP em inteiros de 32 bits. Agora, uma vez que você deu o tamanho, ele se tornou padrão. Tudo o que sabemos sobre a internet dependia disso e depois ficamos sem endereços IP para atribuir. Portanto, se o padrão IP foi revisado para ter 64 bits, tudo vai parar de funcionar, incluindo o roteador (suponho que isso esteja correto) e outros dispositivos de rede. Então, um novo padrão tem que ser criado, que apenas trocou o inteiro de 32 bits por um de 128 bits. E resto ajustado do padrão. Fabricante de hardware só precisa declarar que eles suportam este novo padrão e ele vai se tornar viral. Embora não seja assim tão simples, mas eu acho que você entendeu o ponto aqui.

Aviso Legal: A maioria dos pontos mencionados aqui é fiel à minha suposição. Eu posso ter perdido pontos importantes aqui para torná-lo mais simples. Eu não sou bom com números, então devo ter perdido alguns dígitos, mas meu ponto aqui é responder a resposta do OP sobre por que ele não trava o PC.


13



Eu não downvoted, mas há uma série de problemas com a sua resposta. 1 é 0x31 em ASCII, não 0x1. 1 GB = 1024 ^ 3 B. Wad IPv4 inventado antes de CPUs de 32 bits foram introduzidos, assim dizendo que os endereços foram armazenados em inteiros de 32 bits está em conflito com a questão do OP. E finalmente o IPv6 está usando endereços de 128 bits, não 64 bits. - gronostaj


Nos processadores, há "palavras". Existem palavras diferentes. Quando as pessoas dizem "processador de 32 bits", elas significam principalmente "largura de barramento de memória". Esta palavra consiste em diferentes "campos", que se referem a subsistemas de computador correspondentes a transmissão (24 bits) e controle (outros bits). Eu posso estar errado sobre números exatos, tenha certeza disso através de manuais.

Completamente diferente aspecto é computação. Conjuntos de instruções SSE e MMX podem armazenar inteiros longos. O comprimento máximo sem perda de produtividade depende da versão atual do SSE, mas é sempre sobre o múltiplo de 64bits.

Os processadores Opteron atuais podem manipular números de 256 bits (não tenho certeza sobre o número inteiro, mas a flutuação é certa).

Resumo: (1) a largura do barramento não está conectada diretamente à largura de cálculo, (2) mesmo palavras diferentes (palavra de memória, palavra de registro, palavra de ônibus etc) não conectadas umas às outras, outras têm divisor comum de 8 ou 16 ou 24 Muitos processadores usaram até mesmo palavra de 6 bits (mas sua história).


12



Não é verdade, o processador Pentium original tinha um barramento de dados de 64 bits para alta largura de banda de memória, mesmo sendo um processador de 32 bits. O 8088 era um processador de 16 bits com um barramento de dados de 8 bits. - doug65536