Os computadores de 32 bits podem armazenar apenas números inteiros assinados até 2 31 - 1.
É por isso que ficamos sem endereços IPv4 e entramos na era de 64 bits.
No entanto, o número 2 31 - 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 capaz de exibir bem sem que minha máquina falhe.
Alguém pode explicar por que isso é?
10^9
sem meu PC travar?" mas sim "Como posso escrever10^(18)
sem meu cérebro bater?"Respostas:
Respondo sua pergunta, fazendo uma pergunta diferente:
Você provavelmente conta até o maior número possível com uma mão e depois passa para a segunda mão quando fica sem dedos. Os computadores fazem o mesmo, se precisarem representar um valor maior do que um único registro pode conter, usarão vários blocos de 32 bits para trabalhar com os dados.
fonte
Você está certo de que um número inteiro de 32 bits não pode conter um valor maior que 2 ^ 32-1. No entanto, o valor desse número inteiro de 32 bits e como ele aparece na tela são duas coisas completamente diferentes. A sequência impressa "1000000000000" não é representada por um número inteiro de 32 bits 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 numérico inteiro, mas interpretado individualmente como caracteres ASCII (por exemplo, o caractere '
0
' é representado pelo valor decimal 48, valor binário00110000
), eles podem ser unidos em um formato que faça sentido para você, um humano.Um conceito relacionado na programação é typecasting , que é como um computador irá interpretar um fluxo específico de
0
s e1
s. Como no exemplo acima, ele pode ser interpretado como um valor numérico, um caractere ou até mesmo algo completamente diferente. Embora um número inteiro de 32 bits não consiga manter um valor de 1000000000000, um número de ponto flutuante de 32 bits poderá, usando uma interpretação totalmente diferente.Quanto à forma 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 e bibliotecas especializadas que podem trabalhar com dados arbitrariamente grandes. números.
fonte
1000000000000
exatamente. É 10 ^ 12 ou 2 ^ 12 * 5 ^ 12; 5 ^ 12 requer 28 bits de mantissa.Em primeiro lugar, os computadores de 32 bits podem armazenar números de até 2³²-1 em uma única palavra de máquina . Palavra de máquina é a quantidade de dados que a CPU pode processar de maneira natural (por exemplo, operações com dados desse tamanho são implementadas em hardware e geralmente são mais rápidas de executar). 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.
Pressionando 1uma vez e depois 012 vezes, você está digitando texto. 1entradas
1
, 0entradas0
. Vejo? Você está digitando caracteres. Personagens não são números. As máquinas de escrever não tinham CPU nem memória e estavam lidando muito bem com esses "números", porque é apenas texto.Prova de 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. O significado de 1000000000000 é um número e armazená-lo é uma história diferente (retornaremos a ele em um momento).
Para armazenar o texto (na programação, é chamado string ) 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-máquina. 3 e metade seria suficiente, mas como eu disse, as operações com palavras de máquina são mais rápidas. Vamos supor que o ASCII seja usado para armazenamento de texto, portanto, na memória, será assim: (convertendo códigos ASCII correspondentes a
0
e1
ao binário, cada palavra em uma linha separada)Quatro caracteres se encaixam em uma palavra, o restante é movido para o próximo. O restante é movido para a próxima palavra até que tudo (incluindo o primeiro byte NULL) se encaixe.
Agora, voltando ao armazenamento de números. Funciona exatamente como o texto transbordando, 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:
0..9
Aqui está uma memória vazia de 2 palavras:
Vamos armazenar o número 4:
Agora vamos adicionar 9:
Observe que os dois operandos caberiam em um byte, mas não no resultado. Mas temos outro pronto para usar. Agora vamos armazenar 99:
Novamente, usamos o segundo byte para armazenar o número. Vamos adicionar 1:
Opa ... Isso é chamado de excesso de número inteiro e é uma causa de muitos problemas sérios, às vezes muito caros .
Mas se esperamos que o estouro aconteça, podemos fazer o seguinte:
E agora adicione 1:
Torna-se mais claro se você remover espaços e linhas de separação de bytes:
Previmos que o excesso pode ocorrer e podemos precisar de memória adicional. Manipular números dessa maneira não é tão rápido quanto com números que se encaixam em palavras únicas e precisa ser implementado em software. A adição de suporte para números de palavras de dois e 32 bits a uma CPU de 32 bits o torna efetivamente uma CPU de 64 bits (agora ele pode operar em números de 64 bits nativamente, certo?).
Tudo o que descrevi acima também se aplica à memória binária com bytes de 8 bits e palavras de 4 bytes, funciona da mesma maneira:
Converter esses números para o sistema decimal é complicado, no entanto. (mas funciona muito bem com hexadecimal )
fonte
large as the number 1 trillion (1000000000000)
. Além disso, você está quase falando bignum , mas você nunca mencionar qualquer um dos termos para o que você está dizendo ....Você também pode escrever "ESTA DECLARAÇÃO É FALSA" sem o computador travar :) @ A resposta de Scott é direta para certas estruturas de cálculo, mas sua pergunta de "escrever" um grande número implica que é apenas texto sem formatação, pelo menos até é interpretado.
Editar: agora, com
menos sarcasmo,informações mais úteis sobre diferentes maneiras de armazenar um número na memória. Vou descrevê-los com maior abstração, ou seja, em termos em que um programador moderno pode estar escrevendo código antes de ser traduzido para código de máquina para execução.Os dados em um computador precisam ser restritos a um determinado tipo , e uma definição desse tipo descreve quais operações podem ser executadas nesses dados e como (por exemplo, comparar números, concatenar texto ou XOR um booleano). Você não pode simplesmente adicionar texto a um número, assim como não pode multiplicar um número por texto, para que alguns desses valores possam ser convertidos entre tipos.
Vamos começar com números inteiros não assinados . Nestes tipos de valor, todos os bits são usados para armazenar informações sobre dígitos; o seu é um exemplo de um número inteiro não assinado de 32 bits em que qualquer valor de
0
até2^32-1
pode ser armazenado. E sim, dependendo do idioma ou arquitetura da plataforma usada, você pode ter números inteiros de 16 bits ou números inteiros de 256 bits.E se você quiser ser negativo? Intuitivamente, números inteiros assinados é o nome do jogo. A convenção é alocar todos os valores de
-2^(n-1)
para2^(n-1)-1
- dessa forma, evitamos a confusão de ter que lidar com duas maneiras de escrever+0
e-0
. Portanto, um número inteiro assinado de 32 bits manteria um valor de-2147483648
para2147483647
. Legal, não é?Ok, cobrimos números inteiros que são números sem um componente decimal. Expressar isso é mais complicado: a parte não inteira pode sensivelmente estar apenas em algum lugar entre
0
e1
, portanto, cada bit extra usado para descrevê-la aumentaria sua precisão: 1/2, 1/4, 1/8 ... O problema é que você Não é possível expressar com precisão um decimal simples0.1
como uma soma de frações que só podem ter potências de dois em seu denominador! Não seria muito mais fácil armazenar o número como um número inteiro, mas concordaria em colocar o ponto de raiz (decimal)? Isso é chamado de número de ponto fixo , onde armazenamos,1234100
mas concordamos em uma convenção de lê-lo como1234.100
alternativa.Um tipo relativamente mais comum usado para cálculos é
floating point
. O modo como ele funciona é realmente elegante, ele usa um bit para armazenar o valor do sinal e outros para armazenar o expoente e o significando. Existem padrões que definem essas alocações, mas para um flutuador de 32 bits, o número máximo que você seria capaz de armazenar é um número impressionanteNo entanto, isso tem um custo de precisão. O JavaScript disponível nos navegadores usa flutuadores de 64 bits e ainda não consegue fazer as coisas direito. Basta copiar isso na barra de endereços e pressionar enter. Alerta de spoiler: o resultado não será
0.3
.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 as que entendem matemática, como o mecanismo Wolfram Mathematica, que pode trabalhar com precisão com valores abstratos como o infinito .fonte
A chave é entender como os computadores codificam números.
É verdade que, se um computador insistir 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 poderá armazenar apenas números de até 2 ^ 32. Mas existem muitas outras maneiras de codificar números, dependendo do que você deseja obter com eles.
Um exemplo é como os computadores armazenam números de ponto flutuante. Os computadores podem usar várias maneiras diferentes de codificá-los. O padrão IEEE 754 define regras para codificar números maiores que 2 ^ 32. De maneira grosseira, 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 uma faixa muito maiorde números em termos de tamanho, mas compromete a precisão (o que é bom para muitos propósitos). Obviamente, 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 32 do padrão IEEE permite números com cerca de 7 dígitos decimais de precisão e números de até 10 ^ 96 em magnitude.
Mas existem muitas outras opções se você precisar de precisão extra. Obviamente, você pode usar mais palavras na sua codificação sem limite (embora com uma penalidade de desempenho para converter para dentro e para fora do formato codificado). Se você deseja explorar uma maneira de fazer isso, existe um ótimo suplemento de código-fonte aberto para Excel que usa um esquema de codificação que permite centenas de dígitos de precisão no cálculo. O suplemento é 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 conseguem codificar números maiores. E você pode brincar com os resultados no Excel sem precisar instalar nenhuma ferramenta de programação.
fonte
Está tudo na sua pergunta.
Você pode escrever qualquer número que desejar no papel. Tente escrever um trilhão de pontos em uma folha de papel branca. É 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", "trilhões" e mais, para que você não diga
one one one one one one one one one one one...
em voz alta.Os processadores de 32 bits foram projetados para funcionar de maneira mais rápida e eficiente com blocos de memória com exatamente 32 dígitos binários. Mas nós, pessoas, geralmente usamos sistema numérico de 10 dígitos e computadores, sendo eletrônicos, usamos sistema de 2 dígitos ( binário ). Os números 32 e 64 são potências de 2. Assim, um milhão e um trilhão são potências de 10. É mais fácil operar com esses números do que multidões de 65536, por exemplo.
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 escrever qualquer número que quisermos, e os computadores também, se os projetarmos.
fonte
32 bits e 64 bits referem-se a endereços de memória. A memória do computador é como caixas postais, cada uma com um endereço diferente. A CPU (Unidade Central de Processamento) usa esses endereços para endereçar os locais de memória na sua RAM (Memória de Acesso Aleatório). Quando a CPU suporta apenas endereços de 16 bits, você pode usar apenas 32 MB de RAM (o que parecia enorme na época). Com 32 bits, foi para 4 + gb (o que parecia enorme na época). Agora que temos endereços de 64 bits, a RAM entra em terabytes (o que parece enorme).
No entanto, o programa é capaz de alocar vários blocos de memória para armazenar números e texto, isso depende do programa e não está relacionado ao tamanho de cada endereço. Para que um programa possa informar à CPU, usarei 10 blocos de endereços de armazenamento e armazenarei um número muito grande, uma sequência 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.
fonte
Como a exibição do número é feita usando caracteres individuais, não números inteiros. Cada dígito no número é representado com um literal de caractere separado, cujo valor inteiro é definido pela codificação usada, por exemplo,
'a'
é representado com valor ascii97
, enquanto'1'
é representado por49
. Verifique a tabela ascii aqui .Para exibir 'a' e '1' é o mesmo. Eles são literais de caracteres, não inteiros. É permitido que cada literal de caractere tenha um valor máximo de 255 na plataforma de 32 bits, armazenando o valor no tamanho de 8 bits ou 1 byte (isso depende da plataforma, porém 8 bits é o tamanho de caractere mais comum), portanto, eles podem ser agrupados e podem ser exibido. A quantidade de caracteres separados que eles podem exibir depende da RAM que você possui. Se você tiver apenas 1 byte de RAM, poderá exibir apenas um caractere; se tiver 1 GB de RAM, poderá exibir bem 1024 * 1024 * 1024 caracteres (com preguiça de fazer as contas).
Essa limitação, no entanto, se aplica aos cálculos, no entanto, acho que você está interessado no padrão IPV4. Embora não esteja totalmente relacionado aos
bit-size
, de alguma forma, afetou os padrões. Quando o padrão IPV4 foi criado, eles armazenaram os valores de ip em números inteiros de 32 bits. Agora, uma vez que você deu o tamanho, tornou-se padrão. Tudo o que sabemos sobre internet dependia disso e, em seguida, ficamos sem endereços IP para atribuir. Portanto, se o padrão IP foi revisado para ter 64 bits, tudo simplesmente parou de funcionar, incluindo o seu roteador (presumo que esteja correto) e outros dispositivos de rede. Portanto, um novo padrão deve ser criado, que apenas trocou o número inteiro de 32 bits pelo número um de 128 bits. E resto ajustado do padrão. O fabricante do hardware só precisa declarar que suporta esse novo padrão e ele se torna viral. Embora não seja tão simples, mas acho que você entendeu o ponto aqui.Isenção de responsabilidade: a maioria dos pontos mencionados aqui é fiel à minha suposição. Talvez eu tenha perdido pontos importantes aqui para simplificar. Não sou bom em números, por isso devo ter perdido alguns dígitos, mas meu objetivo aqui é responder à resposta do OP sobre por que ele não trava o PC.
fonte
1
é 0x31 em ASCII, não 0x1. 1 GB = 1024 ^ 3 B. O wad IPv4 inventado antes da introdução de CPUs de 32 bits, portanto, dizer que os endereços foram armazenados em números inteiros de 32 bits está em conflito com a pergunta do OP. E, finalmente, o IPv6 está usando endereços de 128 bits, não de 64 bits.Nos processadores, há "palavras". Há palavras diferentes. Quando as pessoas dizem "processador de 32 bits", elas significam principalmente "largura do 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, certifique-se disso através de manuais.
Um aspecto completamente diferente é a computação. 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 atual do SSE, mas sempre tem múltiplos de 64 bits.
Os atuais processadores Opteron podem lidar com números de 256 bits (não tenho certeza sobre o número inteiro, mas o float é certo).
Resumo : (1) a largura do barramento não está conectada diretamente à largura do cálculo, (2) até mesmo palavras diferentes (palavra de memória, palavra de registro, palavra de barramento etc.) não se conectam entre si; caso contrário, elas têm um divisor comum entre 8 ou 16 ou 24. Muitos processadores até usaram palavras de 6 bits (mas sua história).
fonte
O objetivo de um dispositivo de computação, geralmente, é aceitar, processar, armazenar e emitir dados. O hardware subjacente é apenas uma máquina que ajuda a executar essas quatro funções. Não pode fazer nenhum desses sem software.
Software é o código que informa à máquina como aceitar dados, como processá-los, como armazená-los e como fornecê-los a outras pessoas.
O hardware subjacente sempre terá limitações. No caso de uma máquina de 32 bits, a maioria dos registros que processam dados tem apenas 32 bits de largura. Isso não significa, porém, que a máquina não possa manipular números além de 2 ^ 32, significa que, se você deseja lidar com números maiores, pode levar mais de um ciclo para aceitá-la, processá-la, armazenar ou emita.
O software informa à máquina como lidar com números. Se o software foi projetado para lidar com números grandes, ele envia uma série de instruções para a CPU, que informam como lidar com números maiores. Por exemplo, seu número pode ser representado por dois registradores de 32 bits. Se você quisesse adicionar 1.234 ao seu número, o software instruiria a CPU a adicionar primeiro 1.234 ao registro inferior e depois verificaria o bit de estouro para ver se essa adição resultou em um número muito grande para o registro inferior. Caso isso aconteça, ele adiciona 1 ao registro superior.
Da mesma forma que as crianças em idade escolar são ensinadas a adicionar com carry, a CPU pode ser instruída a lidar com números maiores do que pode conter em um único registro. Isso é verdade para a maioria das operações matemáticas genéricas, para números de qualquer tamanho prático.
fonte
A diferença está em como armazenamos dados em computadores.
Você está certo de que, para uma máquina teórica de 8 bits, só podemos armazenar 2 ^ 8 valores em um único registro de processador ou endereço de memória. (Lembre-se de que isso varia de "máquina" para "máquina" com base no processador usado, na arquitetura da memória etc. Mas, por enquanto, vamos nos ater a uma máquina hipotética de 'estereótipo'.)
Para uma máquina teórica de 16 bits, o valor máximo em um local de registro / memória seria 2 ^ 16, para uma máquina de 32 bits, 2 ^ 32 etc.
Ao longo dos anos, os programadores criaram todo tipo de trapaça para armazenar e manipular números maiores do que os armazenados em um único registro de processador ou endereço de memória. Existem muitos métodos, mas todos envolvem o uso de mais de um endereço de registro / memória para armazenar valores maiores que a largura do local de registro / memória "nativo".
Todos esses métodos são benéficos, pois a máquina pode armazenar / processar valores maiores que sua capacidade nativa. A desvantagem é que quase todas as abordagens exigem várias instruções / leituras / etc. para lidar com esses números. Para o grande número ocasional, isso não é um problema. Ao lidar com muitos números grandes (principalmente endereços de memória grandes), a sobrecarga envolvida torna as coisas mais lentas.
Daí o desejo geral de tornar os registros, locais de memória e hardware de endereço de memória "cada vez mais amplos", para lidar com grandes números "de maneira nativa", para que esses números possam ser manipulados com o número mínimo de operações.
Como o tamanho do número é infinito, o registro do processador / tamanho da memória / endereçamento é sempre um equilíbrio entre o tamanho do número nativo e os custos envolvidos na implementação de larguras cada vez maiores.
fonte
Os computadores de 32 bits podem armazenar apenas números de até 2 ^ 32 em uma única palavra de máquina, mas isso não significa que eles não possam lidar com entidades maiores de dados.
O significado de um computador de 32 bits é geralmente que o barramento de dados e o barramento de endereços têm 32 bits de largura, o que significa que o computador pode lidar com 4 GB de espaço de endereço de memória de uma só vez e enviar quatro bytes de dados por vez no barramento de dados. .
Isso, no entanto, não limita o computador a lidar com mais dados, apenas precisa dividir os dados em blocos de quatro bytes quando é enviado pelo barramento de dados.
O processador Intel de 32 bits comum pode lidar com números de 128 bits internamente, o que permitiria lidar com números como 1000000000000000000000000000000000000000000 sem nenhum problema.
Você pode lidar com números muito maiores do que os de um computador, mas os cálculos precisam ser feitos por software, a CPU não possui instruções para lidar com números maiores que 128 bits. (Ele pode lidar com números muito maiores na forma de números de ponto flutuante, mas você só tem 15 dígitos de precisão.)
fonte
Apenas adicionando uma nota às muitas outras respostas, porque esse é um fato muito importante nesta questão que foi esquecida.
"32 bits" refere-se à largura do endereço de memória. Não tem nada a ver com o tamanho do registro. Muitas CPUs de 32 bits provavelmente possuem registradores de 64 ou até 128 bits. Em particular, referindo-se à linha de produtos x86, as CPUs de consumidor recentes, todas de 64 bits, possuem registros de até 256 bits para fins especiais.
Essa diferença entre a largura do registro e a largura do endereço existe desde os tempos antigos, quando tínhamos registradores de 4 bits e endereços de 8 bits, ou vice-versa.
É simples ver que armazenar um número grande não é problema, independentemente do tamanho do registro, conforme explicado em outras respostas.
A razão pela qual os registros, de qualquer tamanho que eles possam ter, também pode ser calculado com números maiores, é que cálculos muito grandes podem ser divididos em vários menores que se encaixam nos registros (é um pouco mais complicado na realidade).
fonte
As respostas já dadas são realmente muito boas, mas tendem a abordar a questão de lados diferentes e, portanto, apresentam uma imagem incompleta. Eles também são um pouco excessivamente técnicos, na minha opinião.
Então, apenas para esclarecer algo que é sugerido, mas não expresso explicitamente em nenhuma das outras respostas, e que eu acho que é o cerne da questão:
Você está misturando vários conceitos em sua pergunta , e um deles ("32 bits") pode realmente se referir a uma variedade de coisas diferentes (e respostas diferentes assumiram diferentes interpretações). Todos esses conceitos têm algo a ver com o número de bits (1 e 0) usados (ou disponíveis) em vários contextos de computação (o que eu quero dizer com isso será esclarecido pelos exemplos abaixo), mas os conceitos não são relacionados .
Explicitamente:
Observe que isso não pretende ser uma lista abrangente de interpretações para a frase "32 bits".
Crédito extra: para realmente ver a distinção filosófica básica entre números e partes primitivas da memória do computador, leia um pouco sobre as máquinas de Turing .
fonte
Se você escrever 1000000000000, por exemplo, na calculadora, o computador o calculará como um número de tipo Real com ponto decimal . O limite para 32 bits que você mencionou toca mais em todos os números do tipo Inteiro sem ponto decimal. Tipos de dados diferentes usam métodos diferentes para obter bits / bytes.
Números de tipo inteiro : esta tabela pode ajudá-lo a entender o ponto ( http://msdn.microsoft.com/en-us/library/296az74e.aspx ). Isso toca nos limites do C ++. Por exemplo, o número do tipo Int64 possui limites de -9223372036854775808 a 9223372036854775807.
Números de tipo real : números de tipo real contêm valor com ponto flutuante e expoente e você pode inserir números muito maiores, mas com exatidão / precisão limitadas. ( http://msdn.microsoft.com/en-us/library/6bs3y5ya.aspx ) Por exemplo, LDBL (duplo grande) em C ++ tem o expoente máximo 308, portanto, é possível inserir ou ter como resultado um número
9.999 x 10^308
, significa que você teoricamente, 308 (+1) dígitos de9
mas apenas 15 dígitos mais importantes serão usados para representá-lo, o resto será perdido, causa de precisão limitada.Além disso, existem diferentes linguagens de programação e elas podem ter implementações diferentes de limites numéricos. Portanto, você pode imaginar que aplicativos especializados poderiam lidar com números muito maiores (e / ou mais exatos / precisos) que o C ++.
fonte
Caso você queira um exemplo prático de quantos programas em um sistema Linux típico processam um grande número de processamento e saída:
libgmp
- A Biblioteca Aritmética de Precisão Múltipla GNU é a biblioteca mais usada para esse fim em sistemas Linux. Um exemplo simples de multiplicar 2 ^ 80 por 1000:Então, basicamente, é o mesmo que usar os operadores + - * / normais, apenas com uma biblioteca para dividir os números e armazená-los internamente como números múltiplos de tamanho de palavra de máquina (ou seja, 32 bits). Também existem funções do tipo scanf () para manipular a conversão de entrada de texto em tipos inteiros.
A estrutura de
mpz_t
é exatamente como o exemplo de Scott Chamberlain de contar até 6 usando as duas mãos. É basicamente uma matriz demp_limb_t
tipos de tamanho de palavra de máquina e, quando um número é muito grande para caber em uma palavra de máquina, o GMP usa váriosmp_limb_t
para armazenar as partes alta / baixa do número.fonte
Em sua mente, você conhece apenas 10 dígitos diferentes. 0 a 9. Internamente no seu cérebro, isso certamente é codificado de forma diferente do que no computador.
Um computador usa bits para codificar números, mas isso não é importante. Foi assim que os engenheiros escolheram codificar as coisas, mas você deve ignorá-las. Você pode pensar nisso como um computador de 32 bits tem uma representação única de mais de 4 bilhões de valores diferentes, enquanto nós, humanos, temos uma representação única para 10 valores diferentes.
Sempre que precisamos 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 bilhões de valores diferentes também terá que fazer com que o valor mais à esquerda, em um conjunto de valores, seja quatro bilhões de vezes mais importante que o próximo valor nesse conjunto. Na verdade, um computador não se importa. Não atribui "importância" aos números. Os programadores devem criar código especial para cuidar disso.
Sempre que um valor se torna maior que o número de símbolos únicos, 9 na mente dos seres humanos, você adiciona um ao número à esquerda.
Nesse caso, o número ainda cabe em um único "slot"
Portanto, os humanos sempre lidam com o problema de não ter 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 um "sinalizador de estouro" que é gerado nesse caso.
Você pode ter aprendido um método na escola. Um algoritmo O algoritmo é bastante simples. Comece adicionando os dois símbolos mais à esquerda.
Então você passa para o próximo slot e executa a mesma adição.
Como tivemos um estouro, isso significa que precisamos adicionar 1 ao próximo número.
Como não há mais números a serem adicionados, simplesmente criamos um slot e inserimos 1 porque o sinalizador de estouro foi aumentado.
Um computador faz exatamente da mesma maneira, exceto que possui 2 ^ 32 ou até 2 ^ 64 símbolos diferentes, em vez de apenas 10 como seres humanos.
No nível do hardware, o computador trabalha em bits únicos usando exatamente o mesmo método. Felizmente, isso é abstraído para os programadores. Bits tem apenas dois dígitos, porque é fácil de representar em uma linha de energia. A luz está acesa ou apagada.
Finalmente, um computador pode exibir qualquer número como uma simples sequência de caracteres. É nisso que os computadores são melhores. O algoritmo para converter entre uma sequência de caracteres e uma representação interna é bastante complexo.
fonte
Porque você não está exibindo um número (no que diz respeito ao computador), mas uma string ou uma sequência de dígitos. Claro, alguns aplicativos (como a calculadora, eu acho), que lidam com números, podem lidar com esse número, eu acho. Não sei que truques eles usam ... Tenho certeza que algumas das outras respostas mais elaboradas cobrem isso.
fonte
A maior parte do conteúdo desta resposta veio originalmente dessa resposta (escrita antes dessa outra pergunta ter sido marcada como duplicada). Portanto, discuto o uso de valores de 8 bits (embora essa pergunta tenha sido feita sobre valores de 32 bits), mas tudo bem, porque os valores de 8 bits são mais simples de entender conceitualmente, e os mesmos conceitos se aplicam a valores maiores, como a aritmética de 32 bits.
Quando você adiciona dois números de 8 bits, o maior número possível (0xFF + 0xFF = 1FE). De fato, se você multiplicar dois números de 8 bits, o maior número possível (0xFF * 0xFF = 0xFE01) ainda será de 16 bits, duas vezes de 8 bits.
Agora, você pode estar assumindo que um processador x-bit pode acompanhar apenas x-bits. (Por exemplo, um processador de 8 bits pode acompanhar apenas 8 bits.) Isso não é exato. O processador de 8 bits recebe dados em pedaços de 8 bits. (Esses "pedaços" geralmente têm um termo formal: uma "palavra". Em um processador de 8 bits, são usadas palavras de 8 bits. Em um processador de 64 bits, podem ser usadas palavras de 64 bits.)
Portanto, quando você fornece 3 bytes ao computador:
Byte # 1: A instrução MUL
Byte # 2: os bytes de ordem superior (por exemplo, 0xA5)
Byte # 3: os bytes de ordem inferior (por exemplo, 0xCB)
O computador pode gerar um resultado que é mais do que 8 bits. A CPU pode gerar resultados como este:
0100 0000 0100 0010 xxxx xxxx xxxx xxxx 1101 0111
aka:
0x4082xxxxD7
Agora, deixe-me interpretar isso para você:
0x significa apenas que os seguintes dígitos são hexadecimais.
Discutirei momentaneamente o "40".
82 faz parte do registro "A", que é uma série de 8 bits.
xx e xx fazem parte de outros dois registradores, denominados registrador "B" e registrador "C". O motivo pelo qual não preenchi esses bits com zeros ou uns é que uma instrução "ADD" (enviada para a CPU) pode resultar na alteração desses bits pela instrução (enquanto a maioria dos outros bits que eu uso neste exemplo pode seja alterado, exceto por alguns dos bits da flag).
D7 caberia em mais bits, chamado de registro "D".
Um registro é apenas um pedaço de memória. Os registradores são incorporados às CPUs, para que a CPU possa acessar os registradores sem precisar interagir com a memória em um cartão de memória RAM.
Portanto, o resultado matemático de 0xA5 vezes 0xCB é 0x82D7.
Agora, por que os bits foram divididos nos registros A e D em vez dos registros A e B ou nos registros C e D? Bem, mais uma vez, este é um cenário de amostra que estou usando, cujo conceito é bastante semelhante a uma linguagem Assembly real (Intel x86 de 16 bits, conforme usado pelos Intel 8080 e 8088 e muitos CPUs mais recentes). Pode haver algumas regras comuns, como o registro "C" normalmente sendo usado como um índice para operações de contagem (típico para loops) e o registro "B" sendo usado para acompanhar as compensações que ajudam a especificar locais de memória. Portanto, "A" e "D" podem ser mais comuns para algumas das funções aritméticas comuns.
Cada instrução da CPU deve ter alguma documentação, usada por pessoas que programam no Assembly. Essa documentação deve especificar quais registros serão usados por cada instrução. (Portanto, a escolha sobre quais registradores usar é geralmente especificada pelos projetistas da CPU, não pelos programadores da linguagem Assembly. Embora possa haver alguma flexibilidade.)
Agora, voltando ao "40" no exemplo acima: isso é uma série de bits, geralmente chamada de "registro de sinalizadores". Cada bit no registro de sinalizadores tem um nome. Por exemplo, há um bit de "estouro" 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 frequentemente ser chamado pelo nome abreviado de "OF". Isso é o capital, não o zero.) O software pode verificar o valor desse sinalizador e observar o "problema". O trabalho com esse bit geralmente é tratado de forma invisível por linguagens de nível superior; portanto, os programadores iniciantes geralmente não aprendem sobre como interagir com os sinalizadores da CPU. No entanto, os programadores de montagem geralmente podem acessar alguns desses sinalizadores de maneira muito semelhante a outras variáveis.
Por exemplo, você pode ter várias instruções ADD. Uma instrução ADD pode armazenar 16 bits de resultados no registro A e no registro D, enquanto outra instrução pode apenas armazenar os 8 bits baixos no registro A, ignorar o registro D e especificar o bit de estouro. Então, mais tarde (depois de armazenar os resultados do registro A na RAM principal), você poderá usar outra instrução ADD que armazene apenas os 8 bits altos em um registro (possivelmente o registro A.) depende apenas de qual instrução de multiplicação você usa.
(Geralmente, também existe um sinalizador "underflow", caso você subtraia muito para caber no resultado desejado.)
Apenas para mostrar como as coisas ficaram complicadas:
o Intel 4004 era uma CPU de 4 bits
O Intel 8008 era uma CPU de 8 bits. Tinha registros de 8 bits denominados A, B, C e D.
O Intel 8086 era uma CPU de 16 bits. Tinha registros de 16 bits denominados AX, BX, CX e DX.
O Intel 80386 era uma CPU de 32 bits. Ele tinha registros de 32 bits chamados EAX, EBX, ECX e EDX.
As CPUs Intel x64 possuem registros 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 fazer isso, os bits que compõem o registro AX são metade dos bits que compõem o registro EAX, que são metade dos bits que compõem o registro RAX. Portanto, sempre que você altera o valor do AX, também altera o EAX e o RAX, porque esses bits usados pelo AX fazem parte dos bits usados pelo RAX. (Se você alterar o EAX por um valor múltiplo de 65.536, os 16 bits baixos não serão alterados para que o AX não seja alterado. Se você alterar o EAX por um valor que não seja múltiplo de 65.536, isso também afetaria o AX .)
Existem mais sinalizadores e registros do que os que eu mencionei. Simplesmente escolhi alguns usados para fornecer um exemplo conceitual simples.
Agora, se você estiver em uma CPU de 8 bits, ao gravar na memória, poderá encontrar algumas restrições sobre poder se referir a um endereço de 8 bits, não a um endereço de 4 bits ou 16 bits. Os detalhes variam de acordo com a CPU, mas se você tiver essas restrições, a CPU poderá lidar com palavras de 8 bits, e é por isso que a CPU é mais conhecida como "CPU de 8 bits".
fonte