Pregunta Si las máquinas de 32 bits solo pueden manejar números de hasta 2 ^ 32, ¿por qué puedo escribir 1000000000000 (billones) sin que la máquina se cuelgue?


Las computadoras de 32 bits solo pueden almacenar enteros con signo hasta 231 - 1.
Es por eso que nos hemos quedado sin direcciones IPv4 y hemos ingresado a la era de 64 bits.

Sin embargo, el número 231 - 1 (2,147,483,647) no es tan grande como el número 1 billón (1,000,000,000,000) que parezco poder mostrar bien sin que la máquina se cuelgue.

¿Alguien puede explicar por qué es esto?


365


origen


La pregunta es defectuosa Las máquinas de 32 bits pueden manejar números mucho más grandes que 2 ^ 32. Lo hacen todo el tiempo, con 'largo' y así sucesivamente. Solo pueden almacenar hasta 2 ^ 32 en un registro, pero el software está escrito para eludir este problema. Algunos idiomas modernos ni siquiera tienen un problema con la longitud de un número determinado. - JFA
Por favor, mantenga los comentarios en el tema, cortés y relevante a los aspectos técnicos de la pregunta. Ya se han eliminado casi 50 comentarios de broma, y ​​nos gustaría evitar tener que bloquear la publicación. Gracias. - nhinkle♦
Esta pregunta ha sido escrita de una manera un poco descuidada. ¿Qué quiere decir con "escribir" y "mostrar" el número 1000000000000? Cuando escribiste la pregunta, escribiste el número 1000000000000, y tu navegador web lo muestra bien, supongo, pero esto no debería ser extraño para alguien que alguna vez haya usado una computadora. La pregunta pide una interpretación libre. - HelloGoodbye
La conciencia humana se estima que contiene alrededor de 50 bits (lo leí en alguna parte). Entonces la pregunta no es "¿Cómo puedo escribir? 10^9 sin mi PC fallando? "sino más bien" ¿Cómo puedo escribir? 10^(18) sin mi cerebro estrellándose? " - Hagen von Eitzen
Las computadoras de 32 bits solo pueden almacenar números enteros SIN REGISTRO hasta 2 ^ 32 - 1. 2 ^ 32 - 1 ni siquiera equivale a 2.147.483.647 ... 300 votos y nadie se dio cuenta de esto? - Koray Tugay


Respuestas:


Respondo tu pregunta preguntándote una diferente:

¿Cómo cuentas tus dedos hasta 6?

Probablemente cuentes hasta el mayor número posible con una mano, y luego pasas a la segunda mano cuando te quedas sin dedos. Las computadoras hacen lo mismo, si necesitan representar un valor más grande que el que un registro único puede contener, usarán múltiples bloques de 32 bits para trabajar con los datos.


785



Gracioso, @ nombre. Entonces, ¿cómo cuentas con los dedos hasta 32 o más (es decir, una vez que 2 ^ 5 está agotado)? ;) La analogía de moverse a la otra mano es buena ... incluso si el binario retrasa la necesidad de moverse a la otra mano. Lo que me gustaría ver cuenta hasta 1,024 o más con la destreza pediátrica para moverse hasta los dedos para contar aún más en binario - ¡hasta 1,048,575! :) Eso es potencialmente 20 bits de potencia hija. :PAG - J0e3gan
Por favor, mantenga los comentarios sobre el tema y relevante para discutir los aspectos técnicos de esta respuesta. Más de 60 comentarios de broma ya se han eliminado de esta respuesta, y nos gustaría evitar tener que bloquear la publicación. - nhinkle♦
@ codename- easy, asigna un dedo como un puntero de pila. Una vez que se quede sin dedos, agregue la cantidad a la pila y reinicie el recuento. - Makach
¿Dónde aprendiste eso, @Codename? Escuché esto primero de Frederik Pohl, ver p. aquí hjkeen.net/halqn/f_pohl3.htm - Zane
Creo que esta no es la respuesta a la pregunta relevante. Respuesta de @ Bigbio2002 es la correcta. Aquí "1000000000000" no es un número sino un texto, al igual que "adsfjhekgnoregrebgoregnkevnregj". Lo que dices es cierto, pero creo firmemente que esta no es la respuesta correcta. Y ver tantos votos ascendentes ... - Master Chief


Tiene razón en que un entero de 32 bits no puede contener un valor mayor que 2 ^ 32-1. Sin embargo, el valor de este entero de 32 bits y cómo aparece en su pantalla son dos cosas completamente diferentes. La cadena impresa "1000000000000" no está representada por un entero de 32 bits en la memoria.

Para mostrar literalmente el número "1000000000000" requiere 13 bytes de memoria. Cada byte individual puede contener un valor de hasta 255. Ninguno de ellos puede contener el valor numérico completo, sino que se interpreta individualmente como caracteres ASCII (por ejemplo, el carácter '0'está representado por el valor decimal 48, valor binario 00110000), pueden encadenarse en un formato que tenga sentido para ti, un humano.


Un concepto relacionado en la programación es encasillado, que es cómo una computadora interpretará una corriente particular de 0s y 1s. Como en el ejemplo anterior, puede interpretarse como un valor numérico, un carácter o incluso algo completamente diferente. Mientras que un entero de 32 bits puede no ser capaz de contener un valor de 1000000000000, un número de coma flotante de 32 bits podrá hacerlo, utilizando una interpretación completamente diferente.

En cuanto a cómo las computadoras pueden trabajar y procesar grandes números internamente, existen enteros de 64 bits (que pueden acomodar valores de hasta 16 billones de billones), valores de coma flotante, así como bibliotecas especializadas que pueden trabajar con arbitrariamente grandes números.


397



En realidad, eso es en su mayoría correcto, pero no del todo. Es poco probable que un número de punto flotante de 32 puntos represente con precisión 1000000000000. Representará un número muy cercano al número deseado pero no exactamente así. - Tim B
@TimB: ¿Has oído hablar del formato decimal32? Es parte del estándar IEEE 754-2008. Este formato es capaz de una correcta representación de este número :) - V-X
Es cierto, eso puede. Sin embargo, ese no es el formato al que se refieren las personas cuando dicen "flotante", que generalmente se refiere a un número de punto flotante de 32 bits almacenado y utilizado por procesadores de coma flotante estándar en las computadoras actuales. - Tim B
@TimB de hecho. El número más cercano a lo que se puede representar como float32 es 999999995904 - greggo
@TimB: Pero un número de coma flotante de 64 bits puede representar fácilmente 1000000000000 exactamente. Son 10 ^ 12, o 2 ^ 12 * 5 ^ 12; 5 ^ 12 requiere 28 bits de mantisa. - Keith Thompson


En primer lugar, las computadoras de 32 bits pueden almacenar números de hasta 2³²-1 en una sola palabra de máquina. Palabra de máquina es la cantidad de datos que la CPU puede procesar de forma natural (es decir, las operaciones con datos de ese tamaño se implementan en hardware y generalmente son más rápidas de realizar). Las CPU de 32 bits usan palabras que constan de 32 bits, por lo que pueden almacenar números de 0 a 2³²-1. en una palabra.

Segundo, 1 trillón y 1000000000000 son dos cosas diferentes

  • 1 billón es un concepto abstracto de número
  • 1000000000000 es texto

Presionando 1 una vez y luego 0 12 veces estás escribiendo texto. 1 entradas 1, 0 entradas 0. ¿Ver? Estás escribiendo personajes. Los personajes no son números. Las máquinas de escribir no tenían CPU ni memoria y manejaban muy bien esos "números", porque solo se trata de texto.

Prueba de eso 1000000000000 no es un número, sino un texto: puede significar 1 billón (en decimal), 4096 (en binario) o 281474976710656 (en hexadecimal). Tiene aún más significados en diferentes sistemas. El significado de 1000000000000 es un número y almacenarlo es una historia diferente (lo volveremos a ver en un momento).

Para almacenar el texto (en la programación se llama cuerda) 1000000000000 necesita 14 bytes (uno para cada carácter más un byte NULL de terminación que básicamente significa "la cadena termina aquí"). Eso es 4 palabras de máquina. 3 y la mitad sería suficiente, pero como dije, las operaciones en palabras de máquina son más rápidas. Asumamos ASCII se utiliza para el almacenamiento de texto, por lo que en la memoria se verá así: (convirtiendo los códigos ASCII correspondientes a 0 y 1 a binario, cada palabra en una línea separada)

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

Cuatro personajes caben en una palabra, el resto se mueve a la siguiente. El resto se mueve a la siguiente palabra hasta que todo (incluido el primer byte NULL) encaje.

Ahora, volviendo a almacenar números. Funciona igual que con el texto desbordado, pero están ajustados de derecha a izquierda. Puede sonar complicado, así que aquí hay un ejemplo. En aras de la simplicidad, supongamos que:

  • nuestra computadora imaginaria usa decimal en lugar de binario
  • un byte puede contener números 0..9
  • una palabra consta de dos bytes

Aquí hay una memoria vacía de 2 palabras:

0 0
0 0

Guardemos el número 4:

0 4
0 0

Ahora agreguemos 9:

1 3
0 0

Tenga en cuenta que ambos operandos cabrían en un byte, pero no el resultado. Pero tenemos otro listo para usar. Ahora guardemos 99:

9 9
0 0

De nuevo, hemos usado el segundo byte para almacenar el número. Agreguemos 1:

0 0
0 0

Whoops ... Eso se llama desbordamiento de enteros y es una causa de muchos problemas serios, a veces muy costosos.

Pero si esperamos que ocurra un desbordamiento, podemos hacer esto:

0 0
9 9

Y ahora agrega 1:

0 1
0 0

Se vuelve más claro si elimina los espacios de separación de bytes y las nuevas líneas:

0099    | +1
0100

Hemos predicho que el desbordamiento puede ocurrir y es posible que necesitemos memoria adicional. Manejar números de esta manera no es tan rápido como con números que se ajustan a palabras sueltas y tiene que implementarse en el software. Agregar soporte para números de dos palabras de 32 bits a una CPU de 32 bits lo convierte efectivamente en una CPU de 64 bits (ahora puede operar en números de 64 bits de forma nativa, ¿no?).

Todo lo que he descrito anteriormente se aplica a la memoria binaria con bytes de 8 bits y palabras de 4 bytes, funciona de la misma manera:

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

Sin embargo, convertir tales números a un sistema decimal es complicado. (pero funciona bastante bien con hexadecimal)


189



Tu respuesta es bastante condescendiente. OP está hablando claramente del número, no del texto: large as the number 1 trillion (1000000000000). Además, casi estás hablando de Aritmética de precisión arbitraria, pero nunca mencionas ninguno de los términos de lo que dices .... - MirroredFate
"1 billón" es también una cadena - Elzo Valugi
@ElzoValugi Lo es. Tenía que encontrar la forma de presentar el concepto de número abstracto, en lugar de la cadena que representa un número. Creo que "1 billón" es una forma mejor y menos ambigua de hacerlo (ver la prueba en respuesta). - gronostaj
@MirroredFate No estoy de acuerdo con 'está hablando claramente sobre el número'. OP dice 'exhibido bien', que claramente es hablando sobre el texto '1000000000000' para mí ... - Joe
@yannbane 'A' es un personaje y no un número. '?' es un personaje y no un número. '1' es un personaje y no un número también. Los personajes son solo símbolos. Pueden representar dígitos o números, pero definitivamente no son números. '1' puede representar uno, diez, cien, mil y así sucesivamente, es solo un símbolo que representa un dígito que puede ser un número o su parte. '10' (cadena de caracteres) puede significar dos u ocho o diez o dieciséis, etc., pero cuando dices que tienes diez manzanas, estás usando un número diez y todos saben a qué te refieres. Hay una gran diferencia entre los personajes y los números. - gronostaj


También puedes escribir "ESTA DECLARACIÓN ES FALSA" sin que su computadora se cuelgue :) @ La respuesta de Scott es inmediata para ciertos marcos de cálculo, pero su pregunta de "escribir" un número grande implica que es solo texto plano, al menos hasta que sea interpretado.

Editar: ahora con menos sarcasmo más información útil sobre diferentes formas de número se puede almacenar en la memoria. Voy a describir estos con mayor abstracción es decir, en términos que un programador moderno puede escribir código antes de traducirlo a código máquina para su ejecución.

Los datos en una computadora deben estar restringidos a un cierto tipo, y una definición de computadora de ese tipo describe qué operaciones se pueden realizar en estos datos y cómo (es decir, comparar números, concatenar texto o XOR un booleano). No puede simplemente agregar texto a un número, al igual que no puede multiplicar un número por texto, por lo que algunos de estos valores se pueden convertir entre los tipos.

Empecemos con enteros sin signo. En estos tipos de valores, todos los bits se usan para almacenar información sobre dígitos; el tuyo es un ejemplo de Entero sin signo de 32 bits donde cualquier valor de 0 a 2^32-1 puede ser almacenado. Y sí, dependiendo del idioma o la arquitectura de la plataforma utilizada, podría tener enteros de 16 bits o enteros de 256 bits.

¿Qué pasa si quieres obtener un resultado negativo? Intuitivamente, enteros con signo es el nombre del juego. Convención es asignar todos los valores de -2^(n-1) a 2^(n-1)-1 - de esta manera evitamos la confusión de tener que lidiar con dos formas de escribir +0 y -0. Entonces, un entero con signo de 32 bits tendría un valor de -2147483648 a 2147483647. Limpio, ¿no?

Ok, cubrimos números enteros que son números sin un componente decimal. Expresar esto es más complicado: la parte no entera puede ser sensiblemente solo en algún lugar entre 0 y 1, así que cada bit adicional utilizado para describirlo aumentaría su precisión: 1/2, 1/4, 1/8 ... El problema es que no se puede expresar con precisión un decimal simple 0.1 como una suma de fracciones que solo pueden tener poderes de dos en su denominador! ¿No sería mucho más fácil almacenar el número como un número entero, pero acepto poner el punto raíz (decimal) en su lugar? Se llama punto fijo números, donde almacenamos 1234100 pero acordar una convención para leerlo como 1234.100 en lugar.

Un tipo relativamente más común utilizado para los cálculos es floating point. La forma en que funciona es muy clara, usa un bit para almacenar el valor del signo, y luego algunos para almacenar el exponente y el significado. Hay estándares que definen tales asignaciones, pero para un Flotador de 32 bits el número máximo que podría almacenar es abrumador

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

Sin embargo, esto tiene un costo de precisión. JavaScript disponible en navegadores usa flotadores de 64 bits, y todavía no puede hacer las cosas bien. Simplemente copie esto en la barra de direcciones y presione enter. Alerta de spoiler: el resultado es no va a ser 0.3.

javascript:alert(0.1+0.2);

Hay más tipos alternativos como Microsoft .NET 4.5 BigInteger, que teóricamente no tiene límites superiores o inferiores y debe calcularse en "lotes"; pero tal vez las tecnologías más fascinantes son las que entender matemáticas, como el motor Wolfram Mathematica, que puede trabajar con valores abstractos como infinito.


40



Puedes hacer eso en esta realidad. Intenta hacer eso en el universo de Star Trek. Solo quédate atrás antes, debido a todas las chispas y el humo. - Michael Petrotta
Eso no es exactamente cómo funciona el punto fijo. En realidad, es un sistema en el que los números se escalan y sesgan para producir el punto decimal. En su ejemplo, la escala es 1/1000, pero también hay números de punto fijo (especialmente en gráficos de computadora) como este: 0 = 0.0, 255 = 1.0 - la escala es 1/255. - Andon M. Coleman


La clave es entender cómo las computadoras codificar números.

Es cierto que si una computadora insiste en almacenar números usando una representación binaria simple del número usando una sola palabra (4 bytes en un sistema de 32 bits), entonces una computadora de 32 bits solo puede almacenar números de hasta 2 ^ 32. Pero hay muchas otras maneras de codificar los números dependiendo de qué es lo que quiere lograr con ellos.

Un ejemplo es cómo las computadoras almacenan números en coma flotante. Las computadoras pueden usar una gran cantidad de formas diferentes para codificarlas. El estandar IEEE 754 define reglas para codificar números mayores a 2 ^ 32. En bruto, las computadoras pueden implementar esto dividiendo los 32 bits en diferentes partes que representan algunos dígitos del número y otros bits que representan el tamaño del número (es decir, el exponente, 10 ^ x). Esto permite una mucho más grande distancia de números en términos de tamaño, pero compromete la precisión (lo cual está bien para muchos propósitos). Por supuesto, la computadora también puede usar más de una palabra para esta codificación, aumentando la precisión de la magnitud de los números codificados disponibles. La versión simple decimal 32 del estándar IEEE permite números con aproximadamente 7 dígitos decimales de precisión y números de hasta aproximadamente 10 ^ 96 en magnitud.

Pero hay muchas otras opciones si necesita una precisión extra. Obviamente, puede usar más palabras en su codificación sin límite (aunque con una penalización de rendimiento para convertir dentro y fuera del formato codificado). Si desea explorar una forma de hacerlo, existe un gran complemento de código abierto para Excel que utiliza un esquema de codificación que permite cientos de dígitos de precisión en el cálculo. El complemento se llama Xnumbers y está disponible aquí. El código está en Visual Basic, que no es el más rápido posible, pero tiene la ventaja de que es fácil de entender y modificar. Es una excelente forma de aprender cómo las computadoras logran la codificación de números más largos. Y puede jugar con los resultados dentro de Excel sin tener que instalar ninguna herramienta de programación.


31





Todo está en tu pregunta.

Usted puede escribir cualquier número que te guste en el papel. Intenta escribir un trillón de puntos en una hoja blanca de papel. Es lento e ineficaz. Es por eso que tenemos un sistema de 10 dígitos para representar esos grandes números. Incluso tenemos nombres para números grandes como "millones", "billones" y más, así que no dices one one one one one one one one one one one... en voz alta.

Los procesadores de 32 bits están diseñados para funcionar de la manera más rápida y eficiente con bloques de memoria que tienen exactamente 32 dígitos binarios. Pero nosotros, las personas, solemos utilizar un sistema numérico de 10 dígitos, y las computadoras, al ser electrónicas, usan un sistema de 2 dígitos (binario) Los números 32 y 64 simplemente son potencias de 2. Entonces, un millón y un billón son poderes de 10. Es más fácil para nosotros operar con estos números que multitudes de 65536, por ejemplo.

Dividemos números grandes en dígitos cuando los escribimos en papel. Las computadoras descomponen los números en una mayor cantidad de dígitos. Podemos escribir cualquier número que nos guste, y también las computadoras si las diseñamos así.


24





32 bits y 64 bits se refieren a direcciones de memoria. La memoria de su computadora es como cajas de correos, cada una tiene una dirección diferente. La CPU (Unidad Central de Procesamiento) usa esas direcciones para direccionar las ubicaciones de memoria en su RAM (Memoria de Acceso Aleatorio). Cuando la CPU solo podía manejar direcciones de 16 bits, solo podía usar 32 mb de RAM (lo cual parecía enorme en ese momento). Con 32 bits, pasó a 4 + gb (que parecía enorme en ese momento). Ahora que tenemos direcciones de 64 bits, la RAM entra en terabytes (que parece enorme).
Sin embargo, el programa puede asignar múltiples bloques de memoria para cosas como almacenar números y texto, depende del programa y no está relacionado con el tamaño de cada dirección. Entonces un programa puede decirle a la CPU, voy a usar 10 bloques de direcciones de almacenamiento y luego almacenar un número muy grande, o una cadena de 10 letras o lo que sea.
Nota al margen: las direcciones de memoria están apuntadas por "punteros", por lo que el valor de 32 y 64 bits significa el tamaño del puntero utilizado para acceder a la memoria.



15



Buena respuesta, excepto por los detalles: 16 bits de espacio de direcciones le dieron 64 kb, no 32 mb, y máquinas como las 286 tenían direcciones de 24 bits (para 16 mb). Además, con las direcciones de 64 bits, va mucho más allá de los terabytes, más de 16 exabytes, los terabytes tienen el mismo tipo de límites que las motherboards / CPU de la generación actual imponen, no el tamaño de las direcciones. - Phil
32 bits se refiere al tamaño de la palabra de la máquina, no a las direcciones de memoria. Como mencionó Phil, 286 era una CPU de 16 bits, pero usaba 24 bits para direccionar a través de la segmentación de la memoria. Las CPU x86 son de 32 bits, pero usan un direccionamiento de 36 bits. Ver PAE. - gronostaj
@gronostaj y x86 tienen direccionamiento de 32 bits desde 386 hasta Pentium. - Ruslan
Voto a favor porque esta es la única respuesta CORRECTA aquí: 32 bits se refiere al direccionamiento de memoria de 32 bits, no a la aritmética de 32 bits. - user1207217
@ user1207217: ?? Entonces, de acuerdo con su razonamiento, por ejemplo, Z80 o 8080 son procesadores de 16 bits (debido al direccionamiento de memoria de 16 bits y al bus de memoria). - pabouk