La mejor biblioteca de matemática de precisión arbitraria multiplataforma (portátil)

Estoy buscando una buena biblioteca matemática de precisión arbitraria en C o C ++. ¿Podría darme algunos consejos / sugerencias?

Los requisitos principales:

  1. DEBE manejar números enteros arbitrariamente grandes (mi interés principal es en enteros). En caso de que no sepas qué significa la palabra arbitrariamente grande, ¡imagina algo así como 100000! (el factorial de 100000).
  2. La precisión NO DEBE NECESITAR que se especifique durante la inicialización de la biblioteca / creación de objetos. La precisión SÓLO debe estar limitada por los recursos disponibles del sistema.
  3. DEBERÍA utilizar toda la potencia de la plataforma, y ​​debería manejar números “pequeños” de forma nativa. Eso significa que en una plataforma de 64 bits, calcular 2 ^ 33 + 2 ^ 32 debe usar las instrucciones disponibles de la CPU de 64 bits. La biblioteca NO DEBE calcular esto de la misma forma que lo hace con 2 ^ 66 + 2 ^ 65 en la misma plataforma.
  4. DEBE manejar la sum (+), la resta (-), la multiplicación (*), la división entera (/), el rest (%), la potencia (**), el incremento (++), la disminución (-), el gcd () , factorial () y otros cálculos aritméticos enteros comunes de manera eficiente. La capacidad de manejar funciones como sqrt () (raíz cuadrada), log () (logaritmo) que no producen resultados enteros es un plus. La capacidad de manejar cálculos simbólicos es aún mejor.

Esto es lo que encontré hasta ahora:

  1. Las clases BigInteger y BigDecimal de Java : he estado usando estas hasta ahora. He leído el código fuente, pero no entiendo la matemática de abajo. Puede estar basado en teorías / algoritmos que nunca aprendí.
  2. El tipo de enteros integrado o en las bibliotecas principales de bc / Python / Ruby / Haskell / Lisp / Erlang / OCaml / PHP / algunos otros lenguajes: Alguna vez he usado algunos de estos, pero no tengo idea de qué biblioteca están usando , o qué tipo de implementación están usando.

Lo que ya he sabido:

  1. Usar un char como un dígito decimal, y un char * como una cadena decimal y hacer cálculos en los dígitos usando un for-loop.
  2. Usar un int (o un int largo , o un long long ) como una “unidad” básica y una matriz de él como un entero largo arbitrario, y hacer cálculos en los elementos usando for-loop.
  3. Usar un tipo entero para almacenar un dígito decimal (o algunos dígitos) como BCD (decimal codificado en binario) .
  4. Algoritmo de multiplicación de Booth

Lo que no sé

  1. Imprimir la matriz binaria mencionada anteriormente en decimal sin usar métodos ingenuos. Ejemplo de un método ingenuo: (1) agregue los bits del más bajo al más alto: 1, 2, 4, 8, 16, 32, … (2) use una cadena char * mencionada arriba para almacenar los resultados decimales intermedios )

Lo que aprecio:

  1. Buenas comparaciones en GMP , MPFR , decNumber (u otras bibliotecas que sean buenas en su opinión).
  2. Buenas sugerencias sobre libros / artículos que debería leer. Por ejemplo, una ilustración con figuras sobre cómo funciona un algoritmo de conversión binario a decimal no ingenuo es buena. El artículo “Conversión de binario a decimal en precisión limitada” de Douglas W. Jones es un ejemplo de un buen artículo.
  3. Alguna ayuda.

NO responda esta pregunta si:

  1. piensas que usar un doble (o un doble largo o un doble largo ) puede resolver este problema fácilmente. Si lo crees, significa que no entiendes el tema en discusión.

GMP es la elección popular. Squeak Smalltalk tiene una biblioteca muy bonita, pero está escrita en Smalltalk.

Usted pidió libros o artículos relevantes. La parte difícil de los bignums es la división larga. Recomiendo el artículo de Per Brinch Hansen. Revision de la Division de Múltiples Aspectos: Un Recorrido por el Campo de Minas .

En general, la biblioteca de precisión arbitraria de propósito general más rápida es GMP . Si desea trabajar con valores de punto flotante, mire la biblioteca MPFR . MPFR se basa en GMP.

Con respecto al soporte nativo de precisión arbitraria en otros lenguajes, Python usa su propia implementación debido a razones de licencia, tamaño de código y portabilidad de código. El módulo GMPY permite a Python acceder a la biblioteca GMP.

casevh

No he comparado las bibliotecas aritméticas de precisión arbitraria entre sí, pero las personas que parecen haber establecido de manera más o menos uniforme en GMP. Por lo que vale, los números enteros de precisión arbitrarios en GHC Haskell y GNU Guile Scheme se implementan usando GMP, y la implementación más rápida de la referencia de pidigits en el tiroteo del lenguaje se basa en GMP.

Si aún dudas sobre la actualidad, mira también http://ttmath.org

¿Qué hay de Pari? Se basa en GMP superior y proporciona todos los demás beneficios sobre operaciones de teoría de números que siempre necesitará (y muchas cosas de cálculo simbólico).

http://pari.math.u-bordeaux.fr/