Pregunta

Actualmente estoy prestando java.math.BigInteger de las bibliotecas J # como se describe aquí . Como nunca había usado una biblioteca para trabajar con enteros grandes, esto parece lento, en el orden de 10 veces más lento, incluso para números de longitud ulong . ¿Alguien tiene bibliotecas mejores (preferiblemente gratuitas) o este nivel de rendimiento es normal?

¿Fue útil?

Solución

A partir de .NET 4.0 puede usar la clase System.Numerics.BigInteger. Consulte la documentación aquí: http: // msdn.microsoft.com/en-us/library/system.numerics.biginteger(v=vs.110).aspx

Otra alternativa es la clase IntX .

  

IntX es una precisión arbitraria   biblioteca de enteros escrita en puro C #   2.0 con rápido - O (N * log N) - algoritmos de multiplicación / división   implementación. Proporciona todo el   Operaciones básicas en enteros como   Además, multiplicación, comparación,   desplazamiento en modo de bits, etc.

Otros consejos

F # también se envía con uno. Puede obtenerlo en Microsoft.FSharp.Math .

La clase System.Numerics.BigInteger en .NET 4.0 se basa en Microsoft.SolverFoundation.Common.BigInteger de Microsoft Research.

La clase BigInteger de Solver Foundation parece muy eficaz. No estoy seguro de con qué licencia se publica, pero puede obtenerla aquí (descargar e instale Solver Foundation y busque Microsoft.Solver.Foundation.dll).

Reconozco que podría optimizar la implementación si realiza todas las operaciones en BigInts que devolverán resultados más pequeños que un tipo nativo (por ejemplo, int64) en los tipos nativos y solo tratará con la gran matriz si va a rebosar.

editar Esta implementación en codeproject , parece solo 7 veces más lenta ... Pero con el Por encima de la optimización, podría lograr que se desempeñe de forma casi idéntica a los tipos nativos para números pequeños.

Aquí hay varias implementaciones de BigInteger en C #. He usado la implementación BigInteger de Mono, funciona bastante rápido (lo he usado en CompactFramework)

Bouncy Castle

Mono

No estoy seguro del rendimiento, pero IronPython también tiene una clase BigInteger. Está en el espacio de nombres Microsoft.Scripting.Math.

Sí, será lento, y la diferencia 10x es sobre lo que esperaría. BigInt utiliza una matriz para representar una longitud arbitraria, y todas las operaciones deben realizarse manualmente (a diferencia de la mayoría de las matemáticas, que se pueden hacer directamente con la CPU)

Ni siquiera sé si la codificación a mano en el ensamblaje te dará una gran ganancia de rendimiento de más de 10 veces, eso está bastante cerca. Buscaría otras formas de optimizarlo: a veces, dependiendo de tu problema de matemáticas, hay pequeños trucos que puedes hacer para que sea más rápido.

Utilicé Biginteger en un trabajo anterior. No sé qué tipo de rendimiento necesitas. No lo usé en una situación de rendimiento intensivo, pero nunca tuve ningún problema con él.

Esto puede sonar como una sugerencia extraña, pero has probado la decimal para ver qué tan rápido funciona?

El rango decimal es de ± 1.0 × 10 ^ -28 a ± 7.9 × 10 ^ 28, por lo que puede que aún no sea lo suficientemente grande, pero es más grande que un ulong.

Se suponía que había una clase BigInteger en .NET 3.5, pero se cortó .

Esto no te ayudará, pero se suponía que había una clase BigInteger en .Net 3.5; se cortó, pero a partir de declaraciones hechas en PDC, estará en .Net 4.0. Al parecer, han pasado mucho tiempo optimizándolo, por lo que el rendimiento debería ser mucho mejor de lo que está obteniendo ahora.

Además, esta pregunta es esencialmente un duplicado de ¿Cómo puedo representar un entero muy grande en .NET?

Vea las respuestas en este hilo . Deberá usar una de las bibliotecas / clases de enteros grandes de terceros disponibles o esperar a C # 4.0, que incluirá un tipo de datos nativo de BigInteger.

También puede usar Math.Gmp.Native Paquete de Nuget que escribí. Su código fuente está disponible en GitHub , y la documentación está disponible here . Expone a .NET toda la funcionalidad de la biblioteca GMP , que se conoce como una aritmética de precisión arbitraria altamente optimizada. biblioteca.

El entero de precisión arbitraria se representa mediante mpz_t . Las operaciones en estos enteros comienzan con el prefijo mpz_ . Por ejemplo, mpz_add o mpz_cmp . Se proporcionan ejemplos de código fuente para cada operación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top