La mejor plataforma de la cruz (portátil) de precisión arbitraria de matemáticas de la biblioteca

Estoy buscando una buena precisión arbitraria de matemáticas de la biblioteca en C o C++. Podría usted por favor darme algunos consejos /sugerencias?

Los requisitos principales:

  1. Es DEBE manejar arbitrariamente grande enteros (mi principal interés está en números enteros). En caso de que usted no sabe lo que la palabra arbitrariamente grandes medios, imagino algo como 100000! (el factorial de 100000).
  2. La precisión de NO DEBE NECESITAR para ser especificado en la biblioteca de inicialización /creación del objeto. La precisión debe SÓLO ser limitada por los recursos disponibles del sistema.
  3. Es DEBE utilizar toda la potencia de la plataforma, y debe ocuparse de los «pequeños» los números de forma nativa. Eso significa que en una plataforma de 64 bits, el cálculo de la 2^33 + 2^32 deberán hacer uso de la CPU de 64 bits de instrucciones. La biblioteca de NO calcular esto de la misma manera como lo hace con 2^66 + 2^65 en la misma plataforma.
  4. Es DEBE manija de la suma (+), resta (-), multiplicación (*), división de enteros (/), resto (%), alimentación (**), de incremento (++), decremento (–), gcd(), factorial(), y otros comunes aritmética de enteros cálculos de manera eficiente. Capacidad para manejar funciones como la función sqrt() (raíz cuadrada), log() (logaritmo) que no producen resultados entero es un plus. Capacidad para manejar simbólico cálculos es aún mejor.

Aquí está lo que he encontrado hasta ahora:

  1. Javadel BigInteger y BigDecimal de la clase: he estado usando estas tan lejos. He leído el código fuente, pero no entiendo las matemáticas debajo. Puede ser basado en teorías /algoritmos que nunca he aprendido.
  2. La incorporada en el tipo de entero o en el núcleo de las bibliotecas de bc /Python /Ruby /Haskell /Lisp /Erlang /OCaml /PHP /otros idiomas: he utilizado algunos de estos, pero no tengo idea de en qué biblioteca está usando, o que tipo de aplicación que esté utilizando.

Lo que ya he conocido:

  1. Usando un char como un dígito decimal, y un char* como un decimal cadena y hacer cálculos sobre los dígitos mediante un bucle.
  2. El uso de un int (o long int, o mucho) como una básica de la «unidad» y una matriz de él como de un arbitrario entero largo, y hacer cálculos sobre los elementos mediante un for-loop.
  3. El uso de un tipo entero, para almacenar un dígito decimal (o un par de dígitos) como BCD (Binary-coded decimal).
  4. El stand del algoritmo de la multiplicación

Lo que no sé:

  1. La impresión de la matriz binaria se mencionó anteriormente en decimal sin el uso ingenuo de los métodos. Ejemplo de un ingenuo método: (1) añadir los bits de menor a mayor: 1, 2, 4, 8, 16, 32, … (2) el uso de un char* string mencionados anteriormente para almacenar el intermedio decimal resultados).

Lo agradezco:

  1. Buenas las comparaciones en GMP, MPFR, decNumber (o de otras bibliotecas que son buenas en su opinión).
  2. Buenas sugerencias en libros y /o artículos que debo leer. Por ejemplo, una ilustración con las cifras de cómo un onu-ingenuo binario a decimal conversión algoritmo funciona es bueno. El artículo «Binario a Decimal Conversión de Precisión Limitada» por Douglas W. Jones es un ejemplo de un buen artículo.
  3. Cualquier ayuda.

Por favor NO responder a esta pregunta si:

  1. usted piensa que el uso de un double (o long double, o long long double) puede resolver este problema fácilmente. Si piensas así, significa que usted no entiende el tema en discusión.
  • Tan lejos como puedo ver, GMP parece ser una buena biblioteca. Lo que me pregunto es por qué hay una necesidad de que los contribuyentes de Python / Haskell / Erlang / etc para re-inventar la rueda. Si GMP es tan bueno, ¿por qué no confiar en él? La GPL / LGPL licencia puede ser uno de los temas, pero a pesar de ello (y también el modo de redondeo problema), hay otras desventajas de GMP? Es la incorporada en el entero de Python / Haskell / Erlang / cualquier biblioteca de criptografía más rápido que el GMP? Si es así, me gustaría extraer y utilizar, si la licencia lo permite.
  • He encontrado un interesante artículo en cs.uiowa.edu/~jones/bcd/decimal.html por Douglas W. Jones. El artículo describe un método para convertir un entero de 16 bits para la representación decimal utilizando sólo 8 bits aritmética de enteros. La idea es romper el número de 16 bits en 4 nibbles, cada uno representando una base 16 «dígitos». Así, el dígito-0 (n0) representa x1, n1 => x16, n2 => x256, n3 => x4096. Entonces, es obvio que el dígito-0 de número decimal (d0) es dígitos-0 de el resultado de n0 * 1 + n1 * 6 + n2 * 6 + n3 * 6. Por el manejo de la llevar correctamente, d1 a d4 también puede ser calculada.
  • Sin embargo, a medida que yo podía imaginar, Douglas idea anterior podría no ser extendido para manejar arbitrariamente larga binarios enteros. Es porque los números 1 (16^0), 16 (16^1), 256 (16^2) y 4096 (16^3) son pre-calculados. El problema entonces es: ¿cómo representan el 16^n en decimal de n arbitrariamente grande.

5 Kommentare

  1. 24

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

    Se le preguntó por los libros o artículos. La parte difícil de bignums es la división larga. Recomiendo Por Brinch Hansen papel Varios de Longitud División Revisited: Un Recorrido por el campo de Minas.

    • Gracias por tu enlace para el papel! Sí, estoy de acuerdo en que la división es el más complicado. Yo sabía cómo hacer la división a mano con «papel y lápiz métodos» hace mucho tiempo :-), y por lo tanto el mismo método puede ser aplicado a un decimal cadena de char * (cada char que representan un dígito decimal) o un int * de BCD cadena (cada int que representa 4 / 8 / 16 dígitos BCD). Sin embargo, me pregunto si en el mundo real de la producción a nivel de las bibliotecas imita el «papel y lápiz» de método, ya que es demasiado lento.
    • Para ver por qué, vamos a imaginar cómo se ejecuta para 100,000,000,000,000,000 / 333,333,333,333: El primer paso es comparar 100,000,000,000 con 333,333,333,333. Porque el primero es menor que el segundo, el cálculo simplemente se mueve al siguiente dígito. El segundo paso es encontrar el cociente de 1,000,000,000,000 / 333,333,333,333, esto consiste en un ensayo-y-error de multiplicación de 333,333,333,333 * 1 (y * 2, * 3 y * 4), o haciendo sucesivas sustracciones en un bucle. ¿Puedes ver lo lento que es? Yo creo que los algoritmos más eficaces que existen.
    • Brinch Hansen se muestra cómo se puede reducir el ensayo-y-error de método en la mayoría de los dos ensayos. Es realmente muy impresionante.
    • Está bien, me permiten tener una mirada más detallada a la de papel. Gracias!
    • No estoy seguro de que usted terminó de encontrar su solución, ni en qué formato se utiliza para almacenar dígitos, pero COBOL COMP-3 nybble formato es mucho más agradable de tratar, ya que es más compacto, cada 4 bits para almacenar un 0-9 de valor, Y, no es necesario restar hex 30 de la ASCII char valor para obtener un utilizable dígitos.
  2. 13

    Total, él más rápido de propósito general de precisión arbitraria de la biblioteca es GMP. Si quieres trabajar con valores de punto flotante, aspecto en el que el MPFR de la biblioteca. MPFR se basa en GMP.

    Con respecto a los nativos de precisión arbitraria apoyo en otros lenguajes, Python utiliza su propia implementación, debido a que de licencia, el tamaño del código, y el código razones de portabilidad. El GMPY módulo de Python permite acceder a la GMP de la biblioteca.

    casevh

    • Gracias por tu respuesta! Usted ha hablado de «la portabilidad del código». Podría por favor explicar cuál es el problema? Pensé que GMP es portátil y es compatible con las principales plataformas…
    • «la portabilidad del código» no es lo mismo que «apoyado en las principales plataformas». Python utiliza una sencilla aplicación que hace muy pocos supuestos sobre el comportamiento del compilador de C de modo que el mismo código se puede compilar en casi cualquier compilador de C. GMP utiliza más de código (C y altamente sintonizado asamblea) que hacen GMP más rápido, pero también hacer más suposiciones sobre el comportamiento del compilador de C y ensamblador. Por ejemplo, GMP no está bien soportado por Microsoft Visual Studio compiladores. Hay una GMP fork llamado MPIR (www.mpir.org) que hace de soporte de Microsoft compiladores.
    • Lo que yo veo. Esto significa que la implementación de Python es más como ANSI C, mientras que el GMP aplicación utiliza __asm trucos… Gracias por sus explicaciones.
  3. 8

    Ver http://ttmath.org

    Pequeña plantilla de encabezado de la biblioteca sólo para libre uso personal y comercial.

    • Hey! Este es un fácil-a-uso de la biblioteca, y parece ser que utiliza la potencia de la CPU y utiliza algunos de plantillas de C++ magia para completar el trabajo. Gran biblioteca! +1 para ti!
    • Sí, y tiene un permisiva, sin copyleft licencia BSD.
  4. 7

    No lo he comparado con precisión arbitraria aritmética de las bibliotecas de cada uno de los otros de mí mismo, pero las personas que parecen tener más o menos uniforme se establecieron en GMP. Para lo que vale, los enteros de precisión arbitraria en GHC Haskell y GNU Astucia Esquema implementado el uso de GMP, y el más rápido de la aplicación de la pidigits de referencia en el idioma de penaltis se basa en GMP.

    • Gracias! ^___^ Bueno información!
  5. 4

    Lo que acerca de Pari? Está construido en la parte superior de GMP y ofrece todas las otras cosas sobre la teoría del número de operaciones que usted necesitará siempre (y muchos cálculo simbólico cosas).

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

    • Hola fortran(!), se ve buena! Gracias por la información!
    • Usted es bienvenido 🙂 También con Pari se puede rodar rápido de prototipos utilizando GP y cuando estás feliz de escribir la mejor versión en C (y yo creo que se trata de un GP->el compilador de C para ayudar con eso también)

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein