Gagnez des cents avec BigDecimal

Pour pouvoir écrire des programmes Java traitant des finances, vous devez connaître les

BigDecimal

formatage de classe et numérique. La première étape pour vous enseigner ces deux sujets est de commencer par créer

BigDecimal

objets. Nous utiliserons le

BigDecimal

classe dans le

java.math

bibliothèque pour contenir des valeurs. Vous pouvez créer un

BigDecimal

objet de la manière suivante:

Montant BigDecimal = nouveau BigDecimal ("1115.37"); 

Dans le cas ci-dessus, l' Stringargument du BigDecimalconstructeur détermine la valeur de l'objet créé. La valeur de "1115.37"peut représenter, par exemple, un paiement hypothécaire mensuel en dollars ou un solde de chéquier. Pour afficher le montant, vous pouvez utiliser la méthode de la BigDecimalclasse toString():

 System.out.println (montant.toString ()); 

Un programme qui crée et affiche un BigDecimalmontant est illustré ci-dessous:

import java.math. *; Public class Mortgage {public static void main (String [] args) {BigDecimal payment = new BigDecimal ("1115.37"); System.out.println (paiement.toString ()); }}

La sortie du programme ci-dessus est:

1115,37 

Mise en forme de la devise

Puisque nous avons affaire à de l'argent, ce serait bien d'avoir les montants détenus par les BigDecimalobjets correctement formatés, ce qui pour la devise américaine inclurait un signe dollar et une virgule comme séparateur de milliers. (Pour les autres devises, veuillez consulter la section Devise des autres pays ci-dessous). La NumberFormatclasse, trouvée dans la java.textbibliothèque, peut créer un objet approprié pour la devise américaine avec le code suivant:

 NumberFormat n = NumberFormat.getCurrencyInstance (Locale.US); 

Notez que la Localeclasse, utilisée comme argument pour la getCurrencyInstance()méthode ci-dessus, se trouve dans la java.utilbibliothèque.

Le NumberFormat« de format()la méthode que nous utiliserons ensuite, prend une double ou longue primitive comme argument, donc d' abord nous mettre l' BigDecimalobjet en doubleutilisant BigDecimal» s doubleValue()méthode:

double doublePayment = payment.doubleValue (); 

Maintenant, nous utilisons NumberFormatla format()méthode de pour créer un String:

 Chaîne s = n.format (doublePayment); 

En mettant ces étapes dans un programme, nous avons alors:

import java.math. *; import java.text. *; import java.util. *; public class Mortgage2 {public static void main (String [] args) {BigDecimal payment = new BigDecimal ("1115.37"); NumberFormat n = NumberFormat.getCurrencyInstance (Locale.US); double doublePayment = payment.doubleValue (); Chaîne s = n.format (doublePayment); System.out.println (s); }}

La sortie du programme ci-dessus est:

, 115,37 

Les lecteurs doivent noter que la création d'une doublevaleur implique une légère perte de précision de la valeur. Bien que les inexactitudes soient trop petites pour être vues dans les exemples de cet article, elles sont visibles en très grande quantité. Par conséquent, vous ne pouvez pas compter sur NumericFormatpour produire des résultats précis avec de très grands nombres (environ 13 chiffres ou plus).

Devises d'autres pays

Dans l'exemple précédent, nous avons utilisé Locale.UScomme argument passé à la getCurrencyInstance()méthode pour spécifier la devise du pays (États-Unis) avec lequel nous travaillerions. Cependant, Java ne se limite pas à travailler avec la devise américaine. Par exemple, vous utiliseriez Locale.GERMANY, Locale.FRANCEou Locale.ITALYpour spécifier les devises de l'Allemagne, de la France et de l'Italie, respectivement. Le thème de l'internationalisation est un sujet à part entière; voir la section Ressources pour un lien vers plus d'informations.

Opérations BigDecimal

BigDecimalméthodes pour ajouter et soustraire des nombres sont add()et subtract(), respectivement. Par exemple, pour ajouter 1115,37 et 115,37, nous pourrions procéder comme suit:

Balance BigDecimal = nouveau BigDecimal ("1115.37"); Transaction BigDecimal = nouveau BigDecimal ("115.37"); BigDecimal newBalance = balance.add (transaction);

L BigDecimal' newBalanceobjet s contient désormais la valeur 1 230,74. De même, pour soustraire 115,37 de 1115,37, nous pourrions utiliser ce code:

Balance BigDecimal = nouveau BigDecimal ("1115.37"); Transaction BigDecimal = nouveau BigDecimal ("115.37"); BigDecimal newBalance2 = balance.subtract (transaction);

L BigDecimal' newBalance2objet s contient désormais la valeur 1 000,00. (Naturellement, si nous parlons de soldes de chéquiers dans la vie réelle, la subtract()méthode sera utilisée beaucoup plus souvent que la add()méthode, et le montant total soustrait du solde du chéquier dépassera le montant total ajouté, du moins le semble-t-il souvent.) peut accomplir la multiplication et la division avec BigDecimaldes méthodes multiply()et des divide()méthodes. La multiplication est démontrée dans le programme suivant:

import java.math. *; import java.text. *; import java.util. *; public class Multiply {public static void main (String [] args) {BigDecimal d = new BigDecimal ("1115.32"); BigDecimal taxRate = nouveau BigDecimal ("0,0049"); BigDecimal d2 = d.multiply (taxRate); System.out.println ("Non formaté:" + d2.toString ()); NumberFormat n = NumberFormat.getCurrencyInstance (Locale.US); double argent = d2.doubleValue (); Chaîne s = n.format (argent); System.out.println ("Formaté:" + s); }}

La sortie pour le code ci-dessus est indiquée ci-dessous:

Non formaté: 5,465068 Formaté: 0,46 

Notez les décimales supplémentaires dans l' BigDecimalobjet non formaté par rapport à la sortie formatée. De plus, la mise en forme de la valeur de l' BigDecimalobjet entraîne la suppression de la fraction - supérieure à la moitié. Pour gérer les décimales supplémentaires et le manque d'arrondi, nous pouvons utiliser BigDecimalla setScale()méthode de pour définir le nombre de décimales. Lors de l'utilisation setScale(), nous devons spécifier non seulement le nombre de décimales, mais aussi comment le nombre sera arrondi, si l'arrondi est nécessaire. La méthode la plus courante d'arrondi - arrondir les fractions à la moitié ou plus et arrondir toutes les autres fractions à la baisse - peut être spécifiée avec BigDecimalla constante de ROUND_HALF_UP. Par conséquent, pour définir le nombre de décimales sur deux et spécifier que les fractions de moitié et plus seront arrondies, nous pouvons écrire:

d2 = d2.setScale (2, BigDecimal.ROUND_HALF_UP); 

En modifiant le programme ci-dessus pour l'ajouter setScale(), nous avons maintenant:

import java.math. *; import java.text. *; import java.util. *; public class Multiply2 {public static void main (String [] args) {BigDecimal d = new BigDecimal ("1115.32"); BigDecimal taxRate = nouveau BigDecimal ("0,0049"); BigDecimal d2 = d.multiply (taxRate); d2 = d2.setScale (2, BigDecimal.ROUND_HALF_UP); System.out.println ("Non formaté:" + d2.toString ()); NumberFormat n = NumberFormat.getCurrencyInstance (Locale.US); double argent = d2.doubleValue (); Chaîne s = n.format (argent); System.out.println ("Formaté:" + s); }}

Maintenant, la sortie est:

Non formaté: 5,47 Formaté: 0,47 

Maintenant, la BigDecimalvaleur est arrondie à deux chiffres, arrondissant la valeur vers le haut, et le formaté Stringaffiche correctement la valeur arrondie. Les autres constantes utiles pour arrondir sont ROUND_HALF_DOWNet ROUND_HALF_EVEN. Le premier ROUND_HALF_DOWN,, arrondit les fractions de moitié et moins vers le bas, et toutes les autres vers le haut. Le second ROUND_HALF_EVEN,, arrondit les demi-fractions au nombre pair (par exemple, 2,5 arrondis à 2, tandis que 3,5 arrondis à 4), et les fractions supérieures ou inférieures à la moitié au nombre entier le plus proche. Lors de la division d' BigDecimalobjets, nous devons spécifier comment le résultat sera arrondi. Pour cet article, nous arrondirons les moitiés vers le haut. Le programme suivant montre une division d'échantillons:

import java.math. *; import java.text. *; import java.util. *; public class Divide {public static void main (String [] args) {BigDecimal d = new BigDecimal ("1115.32"); BigDecimal jours = nouveau BigDecimal ("30"); BigDecimal d2 = d.divide (jours, 2, BigDecimal.ROUND_HALF_UP); NumberFormat n = NumberFormat.getCurrencyInstance (Locale.US); double argent = d2.doubleValue (); Chaîne s = n.format (argent); System.out.println (s); }}

La sortie du programme ci-dessus est:

7,18 

Calcul des intérêts

For this example, assume that a sum of ,500 will receive interest payments at an annual rate of 6.7 percent. Payments will be calculated quarterly, and we will calculate the first quarterly payment. To do so, we will use the formula I=PRT, where I is the amount of interest, P is the principal (9,500), R is the rate (6.7 percent annually), and T is the time (0.25 years). The program is:

import java.math.*; import java.text.*; import java.util.*; public class Interest { public static void main(String[] args) { BigDecimal principal = new BigDecimal("9500.00"); BigDecimal rate = new BigDecimal("0.067"); BigDecimal time = new BigDecimal("0.25"); BigDecimal temp = principal.multiply(rate); BigDecimal interest = temp.multiply(time); NumberFormat n = NumberFormat.getCurrencyInstance(Locale.US); double money = interest.doubleValue(); String s = n.format(money); System.out.println("First quarter interest: " + s); } } 

Output from the above program is:

First quarter interest: 59.12 

Mutual fund transactions

In this example, an investor owns 754.495 shares in a mutual fund. The investor makes an additional 00.00 purchase of shares at 0.38 per share. We will use the following Java program to answer two questions: How many shares does the investor own after purchase, and what is the current market value of the account after the purchase? We will assume that the mutual fund keeps track of share numbers to three decimal places:

import java.math.*; import java.text.*; import java.util.*; public class Mutual { public static void main(String[] args) { BigDecimal shares = new BigDecimal("754.495"); BigDecimal purchaseAmount = new BigDecimal("200.00"); BigDecimal pricePerShare = new BigDecimal("10.38"); BigDecimal sharesPurchased = purchaseAmount.divide(pricePerShare, 3, BigDecimal.ROUND_HALF_UP); shares = shares.add(sharesPurchased); BigDecimal accountValue = shares.multiply(pricePerShare); NumberFormat n = NumberFormat.getCurrencyInstance(Locale.US); double dAccountValue = accountValue.doubleValue(); String sAccountValue = n.format(dAccountValue); System.out.println("Number of shares = " + shares.toString()); System.out.println("Account value = " + sAccountValue); } } 

The above program outputs:

Number of shares = 773.763 Account value = ,031.66 

More formatting

In the above example, the number of shares happens to be less than 1,000. If it had been greater than 1,000, the program would have outputted the number without a comma to separate the thousands place from the other digits. We can create a NumberFormat object to format numbers in the US style (commas separate thousands, periods separate decimals) by using:

NumberFormat n2 = NumberFormat.getInstance(Locale.US); 

Modifying the previous program to increase the number of shares to more than 1,000 and to display the number of shares formatted as we desire, we have:

import java.math.*; import java.text.*; import java.util.*; public class Mutual2 { public static void main(String[] args) { BigDecimal shares = new BigDecimal("1754.495"); BigDecimal purchaseAmount = new BigDecimal("2000.00"); BigDecimal pricePerShare = new BigDecimal("10.38"); BigDecimal sharesPurchased = purchaseAmount.divide(pricePerShare, 3, BigDecimal.ROUND_HALF_UP); shares = shares.add(sharesPurchased); BigDecimal accountValue = shares.multiply(pricePerShare); NumberFormat n = NumberFormat.getCurrencyInstance(Locale.US); double dAccountValue = accountValue.doubleValue(); String sAccountValue = n.format(dAccountValue); NumberFormat n2 = NumberFormat.getInstance(Locale.US); double dShares = shares.doubleValue(); String sShares = n2.format(dShares); System.out.println("Number of shares = " + sShares); System.out.println("Account value = " + sAccountValue); } } 

The modified version (directly above) now outputs:

Number of shares = 1,947.173 Account value = 0,211.66 

Caveats

If you are writing a program that you or others will depend on for financial calculations, it makes sense to be as careful as possible. First, test your program thoroughly. Second, consult professionals, such as accountants, if you have any doubt as to the correct formula, rounding rule, or any other monetary aspect.

Summing up

BigDecimal objects, which represent values, can be added, subtracted, multiplied, and divided. While you can display BigDecimal objects using the toString() method, it is often preferable to create a NumberFormat object to format doubles obtained from BigDecimal. Now you can add the value of making simple interest calculations and mutual fund transactions in your Java programs.

Robert Nielsen est un programmeur Java 2 certifié Sun. Il est titulaire d'une maîtrise en éducation, spécialisée dans l'enseignement assisté par ordinateur, et a enseigné dans le domaine de l'informatique pendant plusieurs années. Il a également publié des articles sur l'informatique dans divers magazines.