Inteiros grandes em C #
-
05-07-2019 - |
Pergunta
Atualmente estou empréstimos java.math.BigInteger
das bibliotecas # J como descrito aqui . Sem nunca ter usado uma biblioteca para trabalhar com grandes números inteiros antes, isso parece lento, da ordem de 10 vezes mais lento, mesmo para números de comprimento ulong
. Alguém tem alguma bibliotecas melhor (de preferência grátis), ou é este nível de desempenho normal?
Solução
A partir do .NET 4.0 você pode usar a classe System.Numerics.BigInteger. Consulte a documentação aqui: http: // msdn.microsoft.com/en-us/library/system.numerics.biginteger(v=vs.110).aspx
Outra alternativa é o IntX classe.
IntX é uma precisão arbitrária inteiros biblioteca escrita em puro C # 2.0 com rápido - O (N log N) * - algoritmos de multiplicação / divisão implementação. Ele fornece todas as operações básicas sobre números inteiros, como Adicionalmente, a multiplicação, comparando, bit a bit deslocando etc.
Outras dicas
F#
também vem com um. Você pode obtê-lo em Microsoft.FSharp.Math
.
A classe System.Numerics.BigInteger
em .NET 4.0 é baseado em Microsoft.SolverFoundation.Common.BigInteger
da Microsoft Research.
classe BigInteger
da Fundação Solver parece muito alto desempenho. Eu não estou certo sobre qual licença ele é liberado sob, mas você pode obtê-lo aqui (download e instalar Solver Foundation e encontrar o Microsoft.Solver.Foundation.dll).
Eu acho que você poderia otimizar a implementação se você executar todas as operações sobre valores BIGINT que vão retornar resultados menores do que um tipo nativo (Ex. Int64) sobre os tipos nativos e só lidar com a grande variedade se você estiver indo para transbordar.
Editar Este em codeproject , parece apenas 7 vezes mais lento ... Mas com o acima de otimização que você poderia obtê-lo para executar quase idêntica para tipos nativos para pequenos números.
Aqui estão várias implementações de BigInteger em C #. Eu usei implementação BigInteger de Mono, funciona muito rápido (Eu usei-o em CompactFramework)
Eu não tenho certeza sobre o desempenho, mas IronPython também tem uma classe BigInteger. É no namespace Microsoft.Scripting.Math.
Sim, vai ser lento, e 10x diferença é sobre o que eu esperaria. BigInt usa uma matriz para representar um comprimento arbitrário, e todas as operações têm de ser feito manualmente (em oposição a mais de matemática que pode ser feito diretamente com a CPU)
Eu não sei mesmo se a mão de codificação-lo em conjunto lhe dará muito de um ganho de desempenho ao longo de 10x, que é bem perto. Eu olhar para outras formas de otimizá-lo -., Por vezes, dependendo do seu problema de matemática há pequenos truques que você pode fazer para torná-lo mais rápido
BigInteger em um trabalho anterior. Eu não sei que tipo de desempenho que você precisa ter. Eu não usá-lo em uma situação de uso intensivo de desempenho, mas nunca tive qualquer problema com ele.
Isto pode soar como uma sugestão estranha, mas você já testou o decimal digitar para ver o quão rápido ele funciona?
A gama decimal é ± 1,0 × 10 ^ -28 a ± 7,9 × 10 ^ 28, por isso, ainda não pode ser suficientemente grande, mas é maior do que um ulong.
Não era suposto ser uma classe BigInteger no .NET 3.5, mas ficou corte .
Isso não vai ajudá-lo, mas não era para ser uma classe BigInteger na Net 3.5; ele ficou corte, mas a partir de declarações feitas pelo PDC, ele estará em .Net 4.0. Eles aparentemente ter passado muito tempo otimizando-o, de modo que o desempenho deve ser muito melhor do que o que você está recebendo agora.
Além disso, esta questão é essencialmente uma duplicata como posso representar um grande número inteiro em .NET?
Veja as respostas neste fio . Você vai precisar usar um dos terceiros bibliotecas grande inteiros / classes disponíveis ou esperar para C # 4.0, que incluirá um tipo de dados nativo BigInteger.
Este parece muito promissor. É um C # wrapper sobre GMP .
http://web.rememberingemil.org/Projects/GnuMpDotNet/GnuMpDotNet.html
Existem também outras opções BigInteger para .Net aqui em particular, Mpir.Net
Você também pode usar o Math.Gmp.Native pacote Nuget que eu escrevi. Seu código fonte está disponível no GitHub e documentação está disponível aqui . Expõe para .NET toda a funcionalidade do GMP biblioteca que é conhecido como um bignum altamente optimizado biblioteca.
de precisão arbitrária inteiro são representados pelo mpz_t tipo. Operações sobre esses números inteiros começam com o prefixo mpz_
. Para exemplos, mpz_add ou mpz_cmp . exemplos de código fonte são dadas para cada operação.