Grandes números en Java

93

¿Cómo haría los cálculos con números extremadamente grandes en Java?

Lo he intentado, longpero alcanza un máximo de 9223372036854775807, y cuando utilizo un número entero no guarda suficientes dígitos y, por lo tanto, no es lo suficientemente preciso para lo que necesito.

¿Hay alguna forma de evitar esto?

Petey B
fuente
3
9223372036854775807es el valor exacto de Long.MAX_VALUE, de todos modos.
Jin Kwon

Respuestas:

153

Puede usar la BigIntegerclase para enteros y BigDecimalpara números con dígitos decimales. Ambas clases están definidas en java.mathpaquete.

Ejemplo:

BigInteger reallyBig = new BigInteger("1234567890123456890");
BigInteger notSoBig = new BigInteger("2743561234");
reallyBig = reallyBig.add(notSoBig);
Carpeta Fabio Vinicius
fuente
8
Podría valer la pena mencionar el (aunque obvio para la mayoría, supongo) heredar el impacto de rendimiento incurrido por el uso de la clase BigInteger si planea hacer cálculos con eso.
haylem
@haylem, la velocidad de ejecución es la misma, pero la longitud del número hace que sea necesario. utilizan operadores bit a bit para hacer los cálculos. como lo que sucede normalmente cuando se hacen matemáticas con tipos primitivos.
ZOLDIK
18

Aquí hay un ejemplo que obtiene grandes números muy rápidamente.

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
fuente
1
Para números de Fibonacci realmente grandes, el cálculo recursivo consume mucho tiempo. Es mucho mejor usar la fórmula explícita de Binet . Unos pocos Math.pow () sy Math.sqrt () s más tarde, ¡ya está! :)
Zubin Mukerjee
1
@ZubinMukerjee, sin embargo, pow y sqrt en BigDecimal tampoco son baratos. Es mejor que la iteración, pero no tan simple como parece.
Peter Lawrey
13

Checkout BigDecimaly BigInteger.

Clint Miller
fuente
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
fuente
3

Dependiendo de lo que esté haciendo, es posible que desee echar un vistazo a GMP (gmplib.org), que es una biblioteca de precisión múltiple de alto rendimiento. Para usarlo en Java, necesita envoltorios JNI alrededor de la biblioteca binaria.

Vea algunos de los códigos de Alioth Shootout para ver un ejemplo de cómo usarlo en lugar de BigInteger para calcular Pi a un número arbitrario de dígitos.

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

Trevor Tippins
fuente