Grands nombres en Java

93

Comment procéder pour faire des calculs avec des nombres extrêmement grands en Java?

J'ai essayé longmais cela maximise à 9223372036854775807, et lors de l'utilisation d'un entier, il n'enregistre pas suffisamment de chiffres et n'est donc pas assez précis pour ce dont j'ai besoin.

Y a-t-il de toute façon autour de cela?

Petey B
la source
3
9223372036854775807est la valeur exacte de Long.MAX_VALUE, de toute façon.
Jin Kwon

Réponses:

153

Vous pouvez utiliser la BigIntegerclasse pour les entiers et BigDecimalpour les nombres avec des chiffres décimaux. Les deux classes sont définies dans le java.mathpackage.

Exemple:

BigInteger reallyBig = new BigInteger("1234567890123456890");
BigInteger notSoBig = new BigInteger("2743561234");
reallyBig = reallyBig.add(notSoBig);
Reliure Fabio Vinicius
la source
8
Cela vaut peut-être la peine de mentionner le (bien qu'évident pour la plupart, je suppose) l'héritage des performances engendrées par l'utilisation de la classe BigInteger si vous prévoyez de faire des calculs avec cela.
haylem
@haylem la vitesse d'exécution est la même mais la longueur du nombre fait que cela prend du temps. ils utilisent des opérateurs au niveau du bit pour effectuer les calculs. comme ce qui se passe normalement en faisant des maths avec des types primitifs.
ZOLDIK
18

Voici un exemple qui obtient très rapidement de gros chiffres.

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
la source
1
Pour de très grands nombres de Fibonacci, le calcul récursif prend beaucoup de temps. Il vaut mieux utiliser la formule explicite de Binet . Quelques Math.pow () s et Math.sqrt () s plus tard, vous avez terminé! :)
Zubin Mukerjee
1
@ZubinMukerjee cependant pow et sqrt sur BigDecimal ne sont pas bon marché non plus. C'est mieux que l'itération mais pas aussi simple qu'il y paraît.
Peter Lawrey
13

Caisse BigDecimalet BigInteger.

Clint Miller
la source
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
la source
3

En fonction de ce que vous faites, vous voudrez peut-être jeter un œil à GMP (gmplib.org) qui est une bibliothèque multi-précision haute performance. Pour l'utiliser en Java, vous avez besoin de wrappers JNI autour de la bibliothèque binaire.

Voir une partie du code Alioth Shootout pour un exemple de son utilisation à la place de BigInteger pour calculer Pi à un nombre arbitraire de chiffres.

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

Trevor Tippins
la source