Estou brincando com o .NET BigInteger e, basicamente, estou imaginando qual número - uma resposta estimada seria boa - é o ponto de desvio da curva de (o gráfico de (aumento do tempo necessário para operações) vs (valor de BigInteger))?
ou eles são projetados sem esse desvio, de modo que, se traçarmos o aumento do tempo necessário para operações versus o valor do BigInteger de 1 até o infinito, teremos uma curva suave por todo o caminho?
por exemplo, supondo que matrizes sejam projetadas com capacidade de lidar com 50 itens. isso significa que se eu tiver 1 item, as operações serão f (1) time. e quando eu tiver 2 itens, as operações serão f (2) time. se eu tiver 50 itens, as operações são f (50). mas como ele foi projetado para lidar apenas com 50 itens, as operações realizadas quando tivermos 51 itens serão g (51) onde g (51)> f (51).
Se implementada corretamente, a complexidade da aritmética do BigInteger deve ser uma curva suave. Por exemplo, a complexidade temporal da multiplicação deve ser O (NM), onde N é o número de dígitos no primeiro multiplicando e M é o número de dígitos no segundo multiplicando. É claro que existem limites práticos em que você pode escolher N e M tão grandes que os números não cabem em sua máquina.
Existe / alguém conhece algum documento alegando que ele foi implementado como tal?
Respostas:
Qualquer número que possa ser maior que ULong.MaxValue ou menor que Long.MinValue deve ser representado usando BigInteger.
Se NÃO (Long.MinValue <= X <= ULong.MaxValue), então BigInteger
O BigInteger é para números muito grandes do que os primitivos normais podem suportar.
Por exemplo, se seu número inteiro estiver fora do intervalo Long, você provavelmente deve usar o BigInteger. Porém, esses casos são muito raros e o uso dessas classes tem uma sobrecarga significativamente maior do que suas contrapartes primitivas.
Por exemplo,
long
tem 64 bits de largura e pode conter o intervalo: -9.223.372.036.854.775.808 a 9.223.372.036.854.775,80. ulong pode conter de 0 a 18.446.744.073.709.551.615. Se seus números forem maiores ou menores que isso, o BigInteger é sua única opçãoA única vez que os vi usados em um aplicativo do mundo real foi um aplicativo de diagrama de estrelas.
Consulte também: Intervalos primitivos no .NET
fonte
Em certo sentido, o objetivo do BigInteger não é tanto o tamanho absoluto, como é uma precisão ilimitada. Os números de ponto flutuante também podem ser muito grandes, mas com precisão limitada. O BigInteger permite executar aritmética sem se preocupar com erros de arredondamento ou estouro. O preço que você paga é que é centenas de vezes mais lento que a aritmética com números inteiros comuns ou números de ponto flutuante.
Como outros já apontaram, o ulong pode manter-se entre 0 a 18.446.744.073.709.551.615, e enquanto você permanecer nesse intervalo, poderá fazer aritmética exata. Se você ultrapassar 1 ponto acima desse intervalo, haverá uma sobrecarga; portanto, a resposta para sua pergunta é usar o BigInteger se você precisar de aritmética exata e se houver possibilidade de que qualquer resultado intermediário exceda 18.446.744.073.705.515.615.
A maioria dos problemas em ciência, engenharia e finanças pode viver com as aproximações forçadas pelos números de ponto flutuante e não pode arcar com o custo de tempo da aritmética do BigInteger. A maioria dos cálculos comerciais não pode viver com as aproximações da aritmética de ponto flutuante, mas funciona no intervalo de 0 a 18.446.744.073.709.551.615, para que eles possam usar a aritmética comum. O BigInteger é necessário ao usar algoritmos da teoria dos números, que incluem coisas como criptografia (pense em números primos de 50 dígitos). Às vezes, também é usado em aplicações comerciais quando são necessários cálculos exatos, a velocidade não é muito importante e a instalação de um sistema de ponto decimal fixo adequado é um problema demais.
Se implementada corretamente, a complexidade da aritmética do BigInteger deve ser uma curva suave. Por exemplo, a complexidade temporal da multiplicação deve ser O (NM), onde N é o número de dígitos no primeiro multiplicando e M é o número de dígitos no segundo multiplicando. É claro que existem limites práticos em que você pode escolher N e M tão grandes que os números não cabem em sua máquina.
Se você pesquisar "Complexidade computacional do biginteger" no Google, obterá mais referências do que pode usar. Um que fala diretamente à sua pergunta é o seguinte: Comparação de dois pacotes aritméticos de precisão arbitrários .
fonte
Limite de memória
O BigInteger depende da matriz int para armazenamento. Assumindo isso, o limite teórico para o número máximo que o BigInteger é capaz de representar, pode ser derivado do tamanho máximo da matriz disponível em .net. Há um tópico SO sobre matrizes aqui: Descobrindo quanta memória eu posso alocar para uma matriz em C # .
Supondo que sabemos o tamanho máximo da matriz, podemos estimar o número máximo, que o BigInteger pode representar: (2 ^ 32) ^ max_array_size, em que:
Isso fornece um número com 600 milhões de dígitos decimais.
Limite de desempenho
Quanto ao desempenho, o BigInteger usa o algoritmo Karatsuba para multiplicação e o algoritmo linear para adicionar. A complexidade da multiplicação é , o que significa que ela será dimensionada muito bem, mesmo para grandes números ( gráfico de complexidade ), no entanto, você ainda poderá sofrer uma penalidade de desempenho, dependendo do tamanho da RAM e do cache do processador.
Até o momento, como o tamanho máximo do número é limitado a 2 GB, na máquina descendente, você não verá uma lacuna inesperada no desempenho, mas ainda operando com 600 milhões de números de dígitos ficará muito lento.
fonte
O limite é o tamanho da sua memória (e o tempo que você tem). Então, você pode ter números realmente grandes. Como disse Kevin, na criptografia é preciso multiplicar ou exponenciar números com alguns milhares de dígitos (binários), e isso é possível sem problemas.
Obviamente, frequentemente os algoritmos ficam mais lentos à medida que os números aumentam, mas não muito mais lentos.
Quando você estiver usando números no intervalo de mega dígitos, você pode querer pensar em outras soluções - pois o cálculo com elas também fica lento.
fonte
Existem alguns usos na comunidade científica (ou seja, a distância entre galáxias, número de átomos em um campo de grama, etc.)
fonte
double
oufloat
- você não tem a precisão necessária de qualquer maneira.Como sugere a resposta de kevin cline, os BigNumbers foram adicionados às bibliotecas .NET principalmente porque eram necessários como base para muitos algoritmos criptográficos modernos (assinaturas digitais, criptografia de chave pública / privada etc.). Muitos algoritmos criptográficos modernos envolvem cálculos em valores inteiros com tamanhos de até milhares de bits. Como a classe BigNumber descreve uma classe bem definida e útil, eles decidiram torná-la pública (em vez de mantê-la como um detalhe interno das APIs criptográficas).
fonte