? Para una computadora que trabaja con un procesador de 64 bits, el número más grande que puede manejar sería 2 = 18,446,744,073,709,551,616. ¿Cómo maneja los lenguajes de programación, por ejemplo Java o C, C++, la aritmética de números superiores a este valor? Cualquier registro no puede contenerlo como una sola pieza. ¿Cómo se abordó este tema?¿Cómo manejan los lenguajes de programación la aritmética de números enormes
Respuesta
En general, el lenguaje mismo no maneja de alta precisión, de alta precisión gran número aritmética. Es mucho más probable que se escriba una biblioteca que utiliza métodos numéricos alternativos para realizar las operaciones deseadas.
Por ejemplo (sólo estoy haciendo esto ahora mismo), tal biblioteca podría emular las técnicas actuales que puede utilizar para llevar a cabo esa gran aritmética de números con la mano. Dichas bibliotecas generalmente son mucho más lentas que con la aritmética incorporada, pero en ocasiones se requiere precisión y precisión adicional.
Ok, como sea, cuando se trata de operaciones aritméticas, digamos que al sumar los dos números grandes, ambos deben estar en registros, para los cuales el tamaño del registro no es suficiente. ¿Cómo se aborda este problema? – Ajay
Puede realizar una única operación aritmética de gran tamaño realizando muchas más pequeñas. Creo que lo dije con bastante claridad en el segundo párrafo ... –
No agrega 123098712380714091823 a 120497235897345089273403 en una hoja de papel a la vez, ¿o sí? Realiza muchas operaciones más pequeñas, una a la vez. –
Supongo que es incorrecto. El número más grande que puede manejar en un solo registro es un número de 64 bits. Sin embargo, con algunas técnicas de programación inteligente, podría simplemente combinar algunas docenas de esos números de 64 bits en una fila para generar un gran número de 6400 bits y usar eso para hacer más cálculos. Simplemente no es tan rápido como tener el número en un registro.
Incluso los viejos procesadores de 8 y 16 bits utilizado este truco, donde serían simplemente dejar que el desbordamiento de número a otros registros. Hace que las matemáticas sean más complejas, pero no pone fin a las posibilidades.
Sin embargo, estas matemáticas de alta precisión son extremadamente inusuales. Incluso si quiere calcular la deuda nacional total de los EE. UU. Y almacenar el resultado en dólares zimbabuenses, un número entero de 64 bits todavía sería lo suficientemente grande, creo. Sin embargo, definitivamente es lo suficientemente grande como para contener el monto de mi cuenta de ahorros.
no es verdad ... Es especialmente la parte fraccionaria que no quieren redondear a rápido (por ejemplo, cuando se usan números de coma flotante normales) – Toad
@reinier, Donald Knuth ha escrito varios buenos libros y artículos sobre este tema y computadoras y matemáticas en general. Sugiero que comiences a leer algunos de esos. Muchos idiomas tienen una biblioteca BigNum especial, que se puede implementar de muchas maneras. (Ver http://en.wikipedia.org/wiki/Bignum) –
No es inusual ... mmm qué tal ... digamos que quiero 35! .. que cruza el límite fácilmente – Ajay
Como experimento mental, imagina los números almacenados como una cadena. Con funciones para agregar, multiplicar, etc. estos números arbitrariamente largos.
En realidad, estos números son probablemente almacenan en un espacio de manera más eficiente.
pensar en un número de máquina de tamaño como un dígito y aplicar el algoritmo para la multiplicación de varios dígitos de la escuela primaria. Entonces no necesita mantener los números enteros en registros, solo los dígitos mientras se trabajan.
Hay un montón de técnicas especializadas para hacer cálculos en números más grandes que el tamaño de registro. Algunos de ellos se describen en este artículo de la wikipedia en arbitrary precision arithmetic
Los idiomas de bajo nivel, como C y C++, dejan cálculos de números grandes a la biblioteca de su elección. Uno notable es el GNU Multi-Precision library. Los lenguajes de alto nivel, como Python, y otros, integran esto en el núcleo del lenguaje, por lo que los números normales y los números muy grandes son idénticos al programador.
La mayoría de los idiomas los almacena como una matriz de números enteros. Si suma/resta dos de estos números grandes, la biblioteca agrega/resta todos los elementos enteros del conjunto por separado y maneja los acarreos/préstamos. Es como la suma/resta manual en la escuela porque así es como funciona internamente.
Algunos lenguajes utilizan cadenas de texto reales en lugar de matrices enteras, lo que es menos eficiente pero más simple de transformar en representación de texto.
Ada en realidad lo admite de forma nativa, pero solo para sus constantes sin tipo ("números con nombre"). Para las variables reales, debe buscar un paquete de longitud arbitraria. Ver Arbitrary length integer in Ada
+1 Interesante verte en SO, [TED ] (http://stackoverflow.com/users/29639/ted) –
Me di cuenta de que Ada lo soportaba como un built-in, leyendo en otro lugar, pero no sabía que estaba limitado a las constantes. Eso es un poco extraño. ¿Puedes incluso tomar un bignum constante + una pequeña int, y terminar con un resultado bignum? –
Más o menos de la misma manera que que haces. En la escuela, memorizaste suma, multiplicación, sustracción y división de un solo dígito. Luego, aprendió cómo hacer problemas de varios dígitos como una secuencia de problemas de un solo dígito.
Si lo desea, puede multiplicar dos números de veinte dígitos juntos utilizando nada más que el conocimiento de un algoritmo simple y las tablas de multiplicar de un solo dígito.
Eso es cierto, hasta donde llega. Sin embargo, solo hace lo básico: suma, resta, multiplicación y división son solo el comienzo. Entonces, para realmente a los números arbitrarios, debe preocuparse por las raíces cuadradas, el seguimiento de precisión, etc. Es por eso que creo que cada lenguaje debe proporcionar una implementación buena y completa como estándar. –
Los lenguajes de programación que manejan números verdaderamente masivos usan primitivas de números personalizados que van más allá de las operaciones normales optimizadas para CPU de 32, 64 o 128 bits. Estos números son especialmente útiles en la seguridad informática y la investigación matemática.
El GNU Multiple Precision Library es probablemente el ejemplo más completo de estos enfoques.
Puede manejar números más grandes mediante el uso de matrices. Pruébelo en su navegador web. Escriba el siguiente código en la consola JavaScript de su navegador web:
El punto en el que JavaScript no
console.log(9999999999999998 + 1)
// expected 9999999999999999
// actual 10000000000000000 oops!
JavaScript no maneja enteros normales por encima de 9999999999999998
. Pero escribir tu propio número primitivo es hacer que este cálculo funcione es bastante simple. Aquí hay un ejemplo usando a custom number adder class in JavaScript.
Al pasar la prueba usando una clase de número personalizado
// Require a custom number primative class
const {Num} = require('./bases')
// Create a massive number that JavaScript will not add to (correctly)
const num = new Num(9999999999999998, 10)
// Add to the massive number
num.add(1)
// The result is correct (where plain JavaScript Math would fail)
console.log(num.val) // 9999999999999999
Cómo funciona
Usted puede mirar en el código en class Num { ... } para ver los detalles de lo que está sucediendo; pero aquí es un esquema básico de la lógica en uso:
Clases:
- La clase
Num
contiene un conjunto de clases individualesDigit
. - La clase
Digit
contiene el valor de un solo dígito, y la lógica para manejar losCarry flag
Pasos:
- El número elegido se convierte en una cadena
- se gira Cada dígito en una clase
Digit
y almacenada en la claseNum
como una matriz de dígitos - Cuando se incrementa el
Num
, se lleva a cabo o la primeraDigit
en la matriz (la más a la derecha número) - Si el valor
Digit
más laCarry flag
son iguales a laBase
, entonces el siguienteDigit
a la izquierda está llamada a ser incrementado, y el número actual se pone a0
- ... Repetir todo el camino hasta el dígito más a la izquierda de la matriz
Logísticamente es muy similar a lo que sucede en el nivel de la máquina, pero aquí es ilimitada. Puede read more about about how digits are carried here; esto se puede aplicar a los números de cualquier base.
- 1. C#: ¿Cómo debo manejar la aritmética con números enormes?
- 2. Aprendiendo cómo funcionan los lenguajes de programación
- 3. ¿Cómo manejan los diferentes lenguajes el "resto que cuelga"?
- 4. Aritmética con números de iglesia
- 5. Complejidad de los lenguajes de programación
- 6. Lenguajes de programación SIMD
- 7. Automóvil Lenguajes de programación
- 8. Endianness en lenguajes de programación
- 9. Cómo combinar diferentes lenguajes de programación
- 10. ¿Cómo comenzar con NOSQL usando los lenguajes de programación .net?
- 11. ¿Lenguajes de programación verdaderamente multilingües?
- 12. lenguajes de programación no determinista
- 13. Aritmética rápida de números complejos en Clojure
- 14. aritmética de números complejos en Tcl?
- 15. ¿Aprenda los números de programación adecuados?
- 16. Rol de los combinadores en lenguajes de programación concatenativos/tácitos
- 17. Cómo implementar división larga para números enormes (bignums)
- 18. ¿Los lenguajes de programación funcionales son adecuados para la programación de gráficos?
- 19. Convergencia de Matemáticas y Lenguajes de Programación
- 20. ¿Consejos para comprender los lenguajes de programación declarativa?
- 21. Introspección de lenguajes de programación funcional
- 22. Frecuencia de símbolos en lenguajes de programación
- 23. ¿Fuente de analizadores para lenguajes de programación?
- 24. ¿Cuáles son los lenguajes de programación para GPU
- 25. Aritmética de punto fijo en C Programación
- 26. Los lenguajes de programación para el sistema distribuido
- 27. gVim y lenguajes de programación múltiples
- 28. jerarquía chomsky y lenguajes de programación
- 29. ¿Qué lenguajes de programación tienen los intérpretes implementados más fácilmente?
- 30. Ordenando en lenguajes de programación funcional
¿Se trata de una pregunta sobre enteros grandes o sobre cómo se representan los números de coma flotante grandes? – mob
Enteros simplemente para obtener el concepto correcto por ahora :) – Ajay
Hice una pregunta similar y finalmente encontré mi camino aquí; http://stackoverflow.com/questions/1218149/arbitrary-precision-arithmetic-explanation/1218185#1218185 ¡Buena caza! – deau