Números grandes em Java

93

Como eu faria cálculos com números extremamente grandes em Java?

Eu tentei, longmas isso atinge o máximo em 9223372036854775807 e, ao usar um número inteiro, não salva dígitos suficientes e, portanto, não é preciso o suficiente para o que preciso.

Existe alguma maneira de contornar isso?

Petey B
fonte
3
9223372036854775807é o valor exato de Long.MAX_VALUE, de qualquer maneira.
Jin Kwon

Respostas:

153

Você pode usar a BigIntegerclasse para inteiros e BigDecimalpara números com dígitos decimais. Ambas as classes são definidas no java.mathpacote.

Exemplo:

BigInteger reallyBig = new BigInteger("1234567890123456890");
BigInteger notSoBig = new BigInteger("2743561234");
reallyBig = reallyBig.add(notSoBig);
Fábio Vinicius Binder
fonte
8
Pode valer a pena mencionar o (embora óbvio para a maioria, eu acho) o impacto no desempenho de herança incorrido pelo uso da classe BigInteger se você planeja fazer cálculos com isso.
haylem
@haylem a velocidade de desempenho é a mesma, mas o comprimento do número faz com que demore. eles usam operadores bit a bit para fazer os cálculos. como o que acontece normalmente ao fazer matemática com tipos primitivos.
ZOLDIK
18

Aqui está um exemplo que obtém grandes números muito rapidamente.

import java.math.BigInteger;

/*
250000th fib # is: 36356117010939561826426 .... 10243516470957309231046875
Time to compute: 3.5 seconds.
1000000th fib # is: 1953282128707757731632 .... 93411568996526838242546875
Time to compute: 58.1 seconds.
*/
public class Main {
    public static void main(String... args) {
        int place = args.length > 0 ? Integer.parseInt(args[0]) : 250 * 1000;
        long start = System.nanoTime();
        BigInteger fibNumber = fib(place);
        long time = System.nanoTime() - start;

        System.out.println(place + "th fib # is: " + fibNumber);
        System.out.printf("Time to compute: %5.1f seconds.%n", time / 1.0e9);
    }

    private static BigInteger fib(int place) {
        BigInteger a = new BigInteger("0");
        BigInteger b = new BigInteger("1");
        while (place-- > 1) {
            BigInteger t = b;
            b = a.add(b);
            a = t;
        }
        return b;
    }
}
Peter Lawrey
fonte
1
Para números de Fibonacci realmente grandes, o cálculo recursivo é ridiculamente demorado. Muito melhor usar a fórmula explícita de Binet . Alguns Math.pow () se Math.sqrt () s depois, pronto! :)
Zubin Mukerjee
1
@ZubinMukerjee entretanto pow e sqrt em BigDecimal também não são baratos. É melhor do que a iteração, mas não tão simples quanto parece.
Peter Lawrey
13

Check BigDecimal- out e BigInteger.

Clint Miller
fonte
6
import java.math.BigInteger;
import java.util.*;
class A
{
    public static void main(String args[])
    {
        Scanner in=new Scanner(System.in);
        System.out.print("Enter The First Number= ");
        String a=in.next();
        System.out.print("Enter The Second Number= ");
        String b=in.next();

        BigInteger obj=new BigInteger(a);
        BigInteger obj1=new BigInteger(b);
        System.out.println("Sum="+obj.add(obj1));
    }
}
Rupendra Sharma
fonte
3

Dependendo do que você está fazendo, você pode querer dar uma olhada no GMP (gmplib.org), que é uma biblioteca de precisão múltipla de alto desempenho. Para usá-lo em Java, você precisa de wrappers JNI em torno da biblioteca binária.

Veja parte do código do Alioth Shootout para obter um exemplo de como usá-lo em vez de BigInteger para calcular Pi para um número arbitrário de dígitos.

https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/pidigits-java-2.html

Trevor Tippins
fonte