2008-10-07 24 views
64

Actualmente estoy borrowing java.math.BigInteger from the J# libraries as described here. Nunca antes había usado una biblioteca para trabajar con enteros grandes, esto parece lento, del orden de 10 veces más lento, incluso para números de longitud ulong. ¿Alguien tiene bibliotecas mejores (preferiblemente gratuitas), o es este nivel de rendimiento normal?enteros grandes en C#

+0

buen enlace. Un par de gemas allí. –

+3

El único problema es que requieren que se instalen los redistribuibles J #. El hecho de que J # está casi muerto (no fue en VS 2008 al menos) probablemente no ayude a promover eso. –

+0

J # es solo para facilitar la migración de proyectos Java existentes a .NET. Definitivamente no incorporaría ninguna de sus bibliotecas en un nuevo proyecto. – MusiGenesis

Respuesta

63

A partir de .NET 4.0, puede utilizar 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 biblioteca de precisión arbitraria enteros escrito en C# puro 2.0 con rapidez - O (N log N *) - multiplicación/división algoritmos aplicación. Proporciona todas las operaciones básicas con números enteros como suma, multiplicación, comparando, bit a bit cambiando etc.

+26

Para el registro, el ensamblaje 'System.Numerics' no se referencia de manera predeterminada en los proyectos nuevos, por lo que debe agregarse antes de poder utilizar' BigInteger'. –

+0

En el Explorador de soluciones, haga clic con el botón derecho en Referencias> Agregar referencia> Buscar numéricos y verifique la referencia encontrada. Ahora puede agregar "using System.Numerics"; en la parte superior de su archivo .cs – Jan

3

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

2

Sí, será lento, y la diferencia de 10 veces es lo que esperaba. BigInt usa 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 codificar manualmente en el ensamblaje le dará una ganancia de rendimiento de más de 10 veces, eso es bastante cercano. Buscaría otras formas de optimizarlo; a veces, dependiendo de su problema matemático, hay pequeños trucos que puede hacer para hacerlo más rápido.

2

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

2

Esto puede sonar como una sugerencia extraña, pero ¿ha probado el tipo decimal para ver qué tan rápido funciona?

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

Se suponía que debía haber una clase BigInteger en .NET 3.5, pero it got cut.

+0

Sí, vi ese anuncio cuando originalmente buscaba una biblioteca BigInt. Me pone triste. Oh bien. –

+0

Tendría que tener cuidado: usar un decimal podría causar problemas de redondeo. – Blorgbeard

+0

Decimal no causa errores de redondeo. No es un punto flotante. – Kibbee

4

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

edición Este implementation on codeproject, parece sólo 7 veces más lento ... Pero con la optimización mencionada anteriormente podría conseguir que se realice de manera casi idéntica a tipos nativos para los números pequeños.

+0

Creo que la biblioteca J # usa Byte internamente, tiene una función ToByteArray() al menos, y ninguna otra función ToArray(). Esta podría ser una idea si quería hacer mi propia versión, aunque tampoco estoy demasiado emocionado con esa idea. –

+0

¿Con qué tamaño de datos está trabajando, en general? ¿Las cosas desbordan el tamaño de Int64 de forma regular, o es una excepción? –

+0

Lo hago principalmente caso por caso, estableciéndolo en BigInt cuando me encuentro con un desbordamiento con un bloque {} marcado. Si lo hace una vez, es muy probable que lo haga repetidas veces. –

1

Esto no lo ayudará, pero se suponía que debía haber una clase BigInteger en .Net 3.5; se cortó, pero de las declaraciones hechas en PDC, estará en .Net 4.0. Al parecer, han dedicado mucho tiempo a optimizarlo, por lo que el rendimiento debería ser mucho mejor que el que obtendrás ahora.

Además, esta cuestión es esencialmente un duplicado de How can I represent a very large integer in .NET?

+0

BigInteger está en 3.5 pero es una clase interna.;) Es simplemente que no está listo para el horario de máxima audiencia. –

1

Ver las respuestas en este thread. Tendrá que usar una de las librerías/clases de enteros grandes de terceros disponibles o esperar C# 4.0 que incluirá un tipo de datos BigInteger nativo.

9

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

8

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

La clase BigInteger de la Solver Foundation tiene un aspecto muy bueno. No estoy seguro de la licencia bajo la que se publica, pero puede obtenerlo here (descargue e instale Solver Foundation y busque Microsoft.Solver.Foundation.dll).

4

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

Bouncy Castle

Mono

Cuestiones relacionadas