JavaRush /Blog Java /Random-FR /BigInteger et BigDecimal

BigInteger et BigDecimal

Publié dans le groupe Random-FR
En Java, une application est constituée de classes et les classes sont constituées de méthodes et de variables. Les variables, à leur tour, sont divisées en primitives et références. BigInteger et BigDecimal - 1Il existe 8 types de variables en Java et, à l'exclusion booleande et char, elles sont divisées dans les types suivants :
  • entiers : byte, short, intetlong ;
  • virgule flottante (également appelés nombres réels) : floatet double.
Au sein de ces petits groupes, les différences n'existent que dans la plage de valeurs pouvant être contenues (et, par conséquent, l'espace occupé par une telle variable varie). Le plus grand des types entiers est long, avec une plage allant de -9223372036854775808 à 9223372036854775807. Parmi les nombres à virgule flottante, double, avec une plage allant de 1,7e-308 à 1,7e+308. Vous pouvez en savoir plus sur les nombres réels dans cet article . Mais que se passe-t-il si nous devons stocker des nombres supérieurs à la plage acceptable ? Dans ce cas, nous aurons besoin BigIntegerde et BigDecimal.

BigInteger en Java

La classe Java BigIntegerest utilisée comme analogue aux valeurs entières de longueur arbitraire qui n'ont pas la limite de 64 bits de long. De plus, c'est un descendant de la classe Number, comme les wrappers standards pour les types simples numériques - Integer, Long, Byte, Doubleetc. - donc il a des implémentations de méthodes menant à des types simples :
BigInteger value = new BigInteger("32145");

int intValue = value.intValue();//32145

long longValue = value.longValue();//32145

double doubleValue = value.doubleValue();//32145.0
Nous voyons immédiatement la création d'un tel objet BigIntegeravec notre valeur transmise au constructeur, mais au format chaîne. Il est à noter qu'il compte plus d'un créateur, mais pour toutes les occasions. Si les types primitifs ne prennent pas en charge la totalité des données de BigInteger, les données seront tronquées à la plage de ce type primitif. Mais en même temps, il existe des analogues de ces méthodes ( intValueExact(), longValueExact()etc.), la seule différence étant que si le type simple vers lequel la conversion a lieu ne prend pas en charge la plage de données, une ArithmeticException est levée .

Constantes BigInteger

Pour un usage interne, la classe a des constantes :
BigInteger.ZERO
BigInteger.ONE
BigInteger.TEN
Ce sont des objets constants BigIntegeravec respectivement les valeurs 0, 1et 10.

Méthodes BigInteger

L'une des principales caractéristiques de cette classe est qu'elle regorge de méthodes qui implémentent des opérations arithmétiques standard en Java. Par exemple:
  • opérations de sommation :

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.add(secondValue);//73461
  • opérations de multiplication :

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.multiply(secondValue);//1347530670
  • opérations de recherche du reste lors de la division d'un nombre par un autre :

    BigInteger firstValue = new BigInteger("37995");
    BigInteger secondValue = new BigInteger("35466");
    BigInteger resultValue =  firstValue.remainder(secondValue);//2529
  • obtenir la valeur absolue d'un nombre (c'est-à-dire modulo, non signé) :

    BigInteger firstValue = new BigInteger("-37995");
    BigInteger resultValue =  firstValue.abs();//37995
Il existe également des méthodes pour des opérations plus complexes (spécifiques) :
  • opérations avec calcul mod :

    BigInteger firstValue = new BigInteger("-34");
    BigInteger secondValue = new BigInteger("5");
    BigInteger resultValue = firstValue.mod(secondValue); //1
Il existe plusieurs variantes de cette fonction :
  • obtenir un nombre aléatoire et spécifier le nombre de bits que la valeur résultante utilisera :

    BigInteger firstValue = BigInteger.probablePrime(8, new Random());//211
    BigInteger secondValue = BigInteger.probablePrime(16, new Random());//42571
  • opérations de décalage au niveau du bit (ce >> n)

    Décalage vers la gauche :

    BigInteger firstValue = new BigInteger("5");
    BigInteger firstResultValue = firstValue.shiftLeft(3);//40

    Décalage à droite :

    BigInteger secondValue = new BigInteger("34");
    BigInteger secondResultValue = secondValue.shiftRight(2); //8
Bien sûr, il est préférable de consulter la liste complète des méthodes dans la documentation . BigInteger et BigDecimal - 2

BigDecimal en Java

Lorsque nous avons besoin d'un nombre réel de longueur arbitraire, la classe Java est utilisée - BigDecimal. En règle générale, il est utilisé pour travailler avec les finances au lieu de double, car il offre plus d'options de personnalisation. Comme and BigInteger, BigDecimalest un descendant d'une classe Numberet possède des méthodes qui renvoient la valeur d'un objet en tant que type primitif spécifique :
BigDecimal value = new BigDecimal(35563.3);

long longValue = value.longValue();//35563

double doubleValue = value.doubleValue();//35563.3
Comme nous pouvons le voir en réduisant à long, seule la partie entière reste et les décimales sont supprimées.

Constructeurs BigDecimal

Nous examinerons de plus près les constructeurs BigDecimal, car la classe en propose un choix beaucoup plus large. Il existe des constructeurs qui vous permettent de définir la valeur d'un objet de différentes manières (en passant int, long, doubleet Stringmême BigInteger), et il y a ceux qui le permettent. définir les paramètres de l'objet créé (méthodes d'arrondi, nombre de décimales) :
BigDecimal firstValue = new BigDecimal("455656.545");//455656.545
Tout est clair ici, on définit directement la valeur et le nombre de décimales que l'on souhaite voir.
BigDecimal secondValue = new BigDecimal(3445.54);//3445.5399999999999636202119290828704833984375
Les résultats de ce constructeur peuvent être assez imprévisibles, car nous spécifions double, qui de par sa nature est un type très ambigu. Il est donc généralement recommandé de l'utiliser dans un constructeur String.
BigDecimal thirdValue = new BigDecimal(3445.554645675444, MathContext.DECIMAL32);//3445.555
Nous définissons double, mais en même temps nous définissons également un paramètre qui décrit la règle d'arrondi (qui contient le nombre de décimales et l'algorithme d'arrondi).
char[] arr = new String("455656.545").toCharArray();

BigDecimal fourthValue = new BigDecimal(arr, 2, 6);//5656.5
Nous définissons un tableau de caractères à partir duquel nous prenons les valeurs de l'objet et combien de ces éléments nous prenons.
BigDecimal fifthValue = new BigDecimal(new BigInteger("44554"), 3);//44.554
Nous prenons un objet déjà existant BigInteger, définissons le nombre de décimales.

Méthodes BigDecimal

La classe BigDecimalcontient également des méthodes pour diverses opérations arithmétiques, mais BigIntegerelle ne dispose pas de méthodes pour travailler avec des bits, comme . Mais néanmoins, la principale caractéristique BigDecimalest la flexibilité de travailler avec des nombres à virgule flottante. Examinons quelques techniques qui nous donnent le pouvoir de maîtriser les nombres réels :
  • on obtient la précision (nombre de nombres) :

    BigDecimal value = new BigDecimal("454334.34334");
    int result = value.precision();//11
  • définissez le nombre de décimales et la règle d'arrondi :

    BigDecimal firstValue = new BigDecimal(3445.544445);
    
    BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_CEILING);//3445.545

    Ci-dessous, nous examinerons de plus près les constantes permettant de définir des règles d'arrondi.

  • diviser BigDecimalpar un autre BigDecimal, en indiquant le nombre de décimales souhaité et la règle d'arrondi :

    BigDecimal firstValue = new BigDecimal("455656.545");
    
    BigDecimal secondValue = new BigDecimal(3445.544445);
    
    BigDecimal result = firstValue.divide(secondValue, 2,RoundingMode.DOWN);//132.24
  • déplacer une virgule décimale vers la droite/gauche d'un certain nombre de places :

    BigDecimal value = new BigDecimal("455656.545");
    BigDecimal firstResult = value.movePointRight (2);//45565654.5
    BigDecimal secondResult = value.movePointLeft (2);//4556.56545
  • supprimer les zéros à droite :

    BigDecimal value = new BigDecimal("45056.5000");
    BigDecimal result = value.stripTrailingZeros();//45056.5

    Si nous avons tous des zéros dans la partie réelle et qu’il y a aussi des zéros dans la partie entière (ou si nous n’avons aucune décimale), alors :

    BigDecimal value = new BigDecimal("450000.000");
    BigDecimal result = value.stripTrailingZeros();//4.5E+5

Règles d'arrondi BigDecimal

Pour définir les règles d'arrondi, à l'intérieur BigDecimalnous pouvons voir des constantes spéciales qui décrivent les algorithmes d'arrondi : ROUND_UP- arrondi à partir de zéro, arrondi vers la partie réelle :
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult =  firstValue.setScale(1, BigDecimal.ROUND_UP );//2.6
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_UP );//-2.5
ROUND_DOWN— arrondi à zéro, c'est-à-dire troncature de la partie réelle :
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult =  firstValue.setScale(1, BigDecimal.ROUND_DOWN  );//2.5
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_DOWN  );//-2.6
ROUND_CEILING— arrondi à l'infini positif. Autrement dit, si notre nombre est positif, alors -> ROUND_UP, s'il est négatif, alors ->ROUND_DOWN
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult =  firstValue.setScale(1, BigDecimal.ROUND_CEILING);//2.6
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_CEILING);//-2.5
ROUND_FLOOR- arrondir à l'infini négatif, c'est-à-dire si notre nombre est positif, alors -> ROUND_DOWN, s'il est négatif, alors ->ROUND_UP
BigDecimal firstValue = new BigDecimal("2.578");
BigDecimal firstResult =  firstValue.setScale(1, BigDecimal.ROUND_FLOOR);//2.5
BigDecimal secondValue = new BigDecimal("-2.578");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_FLOOR);//-2.6
Pour la valeur considérée, nous considérerons ce nombre le plus proche avec une décimale tronquée comme le plus proche voisin du nombre considéré. Par exemple, 2,43 sera plus proche de 2,4 que de 2,5, mais 2,48 sera plus proche de 2,5. ROUND_HALF_DOWN— arrondi au « voisin le plus proche ». Si les deux voisins sont à égale distance d’une valeur particulière, un arrondi à zéro est effectué. Équidistant est, par exemple, lorsque le nombre à arrondir est 5, et qu'il est à la même distance de 0 et 10) :
BigDecimal firstValue = new BigDecimal("2.58");
BigDecimal firstResult =  firstValue.setScale(1, BigDecimal.ROUND_HALF_DOWN );//2.6
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_HALF_DOWN );//2.5
ROUND_HALF_UP— mode d'arrondi au « voisin le plus proche ». Si les deux voisins sont équidistants, l'arrondi est effectué (c'est le même arrondi qu'on nous a appris à l'école) :
BigDecimal firstValue = new BigDecimal("2.53");
BigDecimal firstResult =  firstValue.setScale(1, BigDecimal.ROUND_HALF_UP  );//2.5
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_HALF_UP  );//2.6
ROUND_HALF_EVEN— arrondi au « voisin le plus proche » si les deux voisins ne sont pas équidistants. Dans ce cas, si le nombre à arrondir est précédé d'un nombre impair, il est arrondi au supérieur, et s'il est pair, il est arrondi à l'inférieur :
BigDecimal firstValue = new BigDecimal("2222.2225");
BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_HALF_EVEN );//2222.222
Nous obtenons ce résultat car en arrondissant, 5 regarde le chiffre 2 précédent, et voyant qu'il est pair, arrondit à l'inférieur. Mais si:
BigDecimal firstValue = new BigDecimal("2222.22255");
BigDecimal secondValue = firstValue.setScale(3,BigDecimal.ROUND_HALF_EVEN );//2222.223
Cet arrondi augmente, puisque les 5 derniers regardent la valeur précédente et voient un nombre impair. En conséquence, le nombre est arrondi à 6, après quoi le 6 suivant est également arrondi. Mais le six ne regarde plus le chiffre de gauche, puisque le chiffre est nettement plus proche vers le haut, et du coup les 2 derniers sont augmentés de 1. ROUND_UNNECESSARY- sert à vérifier que le chiffre n'a pas besoin d'être arrondi. C'est-à-dire que nous vérifions que le nombre a le nombre requis de décimales :
BigDecimal firstValue = new BigDecimal("2.55");
BigDecimal firstResult =  firstValue.setScale(2, BigDecimal.ROUND_UNNECESSARY);//2.55
Tout va bien ici, la valeur a deux chiffres et on vérifie qu'il n'y a que deux chiffres après la virgule. Mais si:
BigDecimal secondValue = new BigDecimal("2.55");
BigDecimal secondResult = secondValue.setScale(1, BigDecimal.ROUND_UNNECESSARY);
Ensuite, nous obtenons - ArithmeticException, puisque la valeur testée dépasse le nombre spécifié de décimales. Mais si nous vérifions deux décimales, mais qu'en fait il y en a une, alors l'exception ne sera pas levée et les chiffres manquants sont simplement complétés par des zéros :
BigDecimal thirdValue = new BigDecimal("2.5");
BigDecimal thirdResult = thirdValue.setScale(3, BigDecimal.ROUND_UNNECESSARY   );//2.500
Je voudrais également noter que y BigDecimala des constantes similaires aux constantes BigInteger ZERO, ONEet TEN. Voici un lien vers la documentation . Et enfin : comme vous l'avez probablement remarqué, lorsque nous effectuons des opérations avec des objets BigIntegeret BigDecimal, nous ne modifions pas les anciens, mais en obtenons toujours de nouveaux. Cela nous indique qu'ils sont immutable, c'est-à-dire immuables après leur création, tout comme String. En d’autres termes, toutes leurs méthodes ne peuvent pas changer l’état interne de l’objet ; elles peuvent tout au plus renvoyer un nouvel objet avec les paramètres spécifiés par la fonction que nous utilisons.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION