Intro To Java: Section 3.1 - BigDecimals
BigDecimals
Unfortunately none of the primitive data types are apropriate for storing currency. Integers and longs cannot hold decimals. Floats and doubles are not percise enough to represent currency. If we used floats and doubles to perform calculations in important financial systems the values could regularly be off by one penny or more. Balances would be off, customers would be angry, and accounting would be impossible. This is where the BigDecimal object comes into play - BigDecimals are specialized objects which are appropriate for storing currency values. BigDecimals are immutable objects meaning once you create it its value cannot be changed directly - in order to perform computations you must use the appropriate BigDecimal methods and create entirely new BigDecimals. In order to access this class in your program, it must be properly imported in the same manner as the Scanner object from the previous topic. In order to import and use Big Decimals, you must access it from the math package of the Java API.import java.math.BigDecimal;
BigDecimal myDecimal = new BigDecimal("250.05");
//Create Big Decimals //Note - We are passing the argument as a string instead of a double (note the quotes) // the quotation marks are optional here but this prevents rounding errors. BigDecimal decimalOne = new BigDecimal("10.00"); BigDecimal decimalTwo = new BigDecimal("5.00"); //Operation Examples using BigDecimal methods //Addition decimalAdditionResult = decimalOne + decimalTwo BigDecimal decimalAdditionResult = decimalOne.add(decimalTwo); //Subtraction decimalSubtractionResult = decimalOne - decimalTwo BigDecimal decimalSubtractionResult = decimalOne.subtract(decimalTwo); //Multiplication decimalProductResult = decimalOne * decimalTwo BigDecimal decimalProductResult = decimalOne.multiply(decimalTwo); //Division decimalDivisionResult = decimalOne / decimalTwo BigDecimal decimalDivisionResult = decimalOne.divide(decimalTwo);
Although BigDecimals are immutable objects, it is possible to "change" their values indirectly by updating their reference variable. Technically, you are not changing the value of the BigDecimal, but instead are creating an entirely new BigDecimal object to which the old variable name references. For example, you could add a second BigDecimal to a first BigDecimal using the .add() method - this returns an entirely new BigDecimal to which you can reference using the old name. This works because we are not directly modifying the values of the original BigDecimal, but are replacing it with a new BigDecimal that has the same name.
import java.math.BigDecimal; public class Topic03Demos { public static void main(String[] args) { //Create BigDecimals BigDecimal someDecimal = new BigDecimal("14.00"); BigDecimal otherDecimal = new BigDecimal("6.00"); //Add otherDecimal to someDecimal someDecimal = someDecimal.add(otherDecimal); //Print System.out.println("The value of someDecimal is " + someDecimal.toString()); } }
The value of someDecimal is 20.00Note that if you are doing this, you must always do it in this format: "someDecimal = someDecimal.add(otherDecimal);" - you cannot just have "someDecimal.add(otherDecimal);"
The diagram below illustrates what happens in the previous example.
Given this knowledge, it is also possible to change the value of the BigDecimal by having it reference a new BigDecimal.
import java.math.BigDecimal; public class Topic03Demos { public static void main(String[] args) { //Create BigDecimals BigDecimal aDecimal = new BigDecimal("14.00"); System.out.println("The value of aDecimal is: " + aDecimal.toString()); //Reference a new BigDecimal aDecimal = new BigDecimal("10.00"); System.out.println("The value of aDecimal is: " + aDecimal.toString()); } }
The value of aDecimal is: 14.00 The value of aDecimal is: 10.00
Printing Results
You may print out the results in the same manner that we printed out the values of variables in the previous sections. Note that Java is actually converting the value of the BigDecimal into a string automatically. This means we don't have to manually convert the BigDecimal into another primitive data type such as a double before we print out its result.//Printing out results - Java automatically converts BigDecimals to Strings for output System.out.println("Addition result is: " + decimalAdditionResult); System.out.println("Subtraction result is: " + decimalSubtractionResult); System.out.println("Product result is: " + decimalProductResult); System.out.println("Divison result is: " + decimalDivisionResult);
Addition result is: 15.00 Subtraction result is: 5.00 Product result is: 50.0000 Divison result is: 2It is also possible to manually convert the BigDecimal to a string and then print out its value. Note that the two examples below are basically the same thing - we're just printing out two concatenated strings.
//Convert to String - option one String resultString = decimalAdditionResult.toString(); System.out.println("Result is: " + resultString); //All in one step - option two System.out.println("Result is: " + decimalAdditionResult.toString());
Result is: 15 Result is: 15Alternatively, you could manually convert the BigDecimals to doubles and then print the values out to whatever amount of spaces you want using the proper format specifiers. BigDecimals can be converted to doubles using the .doubleValue method.
//Convert Result to Double double additionResult = decimalAdditionResult.doubleValue(); System.out.printf("The addition result to two decimal places is %.2f",additionResult);
The addition result to two decimal places is 15.00Just like the string result of the BigDecimal can be printed using one line of code - we can also print out the double result for the BigDecimal using one line of code by throwing the BigDecimal.doubleValue directly into the print method's arguments.
System.out.printf("The addition result to two decimal places is %.2f",decimalAdditionResult.doubleValue());
Setting Scale To Control Rounding
In addition to being able to control the amount of decimal places in BigDecimals by converting them to doubles you can also use the BigDecimal setScale method. This is the preferred way to do it because it gives you control over exactly how your decimals will be rounded. After creating your BigDecimal, you can use the setScale method to define the amount of decimal places you would like the BigDecimal to go to. In most cases with currency you will be using a value of 2 to go to two decimal places. The format for creating a BigDecimal with a set scale is as follows:BigDecimal someDecimal = new BigDecimal("value").setScale(scale, roundingMode);
- BigDecimal.ROUND_CEILING: Rounds to the next highest number (1.222 -> 1.23) (-1.222 -> -1.22)
- BigDecimal.ROUND_DOWN: Rounds in the direction of zero (1.222 -> 1.22) (-1.222 -> -1.22)
- BigDecimal.ROUND_FLOOR: Rounds to the next lowest number (1.222 -> 1.22) (-1.222 -> -1.23)
- BigDecimal.ROUND_HALF_UP: Rounds up if the decimal is >= 5 (1.225 -> 1.23) (1.224 -> 1.22)
- BigDecimal.ROUND_HALF_DOWN: Rounds down if the decimal is <= 5 (1.225 -> 1.22) (1.226 -> 1.23)
import java.math.BigDecimal; public class Topic03Demos { public static void main(String[] args) { //Create a BigDecimal BigDecimal someDecimal = new BigDecimal("14.555").setScale(2, BigDecimal.ROUND_HALF_UP); //Print System.out.println("The value of someDecimal is " + someDecimal.toString()); } }
The value of someDecimal is 14.56The output was 14.56 because 14.555 was rounded up to 14.56.
Unreferenced Objects With BigDecimals
In Java, it is possible to create unreferenced objects, which are not referenced by name. This is especially useful in situations where you want to create an object for a single purpose and then get rid of it. The example below illustrates how we would typically add 10 to a BigDecimal object - by creating a second BigDecimal which holds the values we want to add and then combining the two BigDecimals and storing them in a third BigDecimal which stores the total sum.import java.math.BigDecimal; public class Test { public static void main(String[] args) { //Adding 5 to aBigDecimal //Create aBigDecimal BigDecimal aBigDecimal = new BigDecimal("5"); BigDecimal bBigDecimal = new BigDecimal("10"); //Add the two together and store result in sumDecimal BigDecimal sumDecimal = aBigDecimal.add(bBigDecimal); //Print Results System.out.println("aBigDecimal + 10 = " + sumDecimal.toString()); } }
aBigDecimal + 10 = 15But what if you want to add 10 to aBigDecimal without creating bBigDecimal to store the value of 10? If you're only using the value 10 one time to perform one computation it's quite tiresome to create a second bBigDecimal object. This can be simplified by using an unreferenced object. You can create unreferenced objects without names directly in the arguments for the BigDecimal arithmetic methods.
import java.math.BigDecimal; public class Test { public static void main(String[] args) { //Adding 5 to aBigDecimal //Create aBigDecimal BigDecimal aBigDecimal = new BigDecimal("5"); //Add 10 to aBigDecimal and store the result in sumDecimal BigDecimal sumDecimal = aBigDecimal.add(new BigDecimal("10")); //Print Results System.out.println("aBigDecimal + 10 = " + sumDecimal.toString()); } }
aBigDecimal + 10 = 15The result is the same as in the previous example, but the method is different. We added "(new BigDecimal("10")" directly inside the arguments for the BigDecimal addition method. This created an unreferenced BigDecimal object with the value of 10 so we didn't have to create a second bBigDecimal to perform the one time computation.
Scanners With BigDecimals
It is important to understand how to get user input and store it as a BigDecimal. The method works quite similarly to how it did in the previous lesson. The example below demonstrates how you can ask a user to give you a monetary value and then print that value to the screen.import java.math.BigDecimal; import java.util.Scanner; public class Topic03Demos { public static void main(String[] args) { //Create a scanner Scanner userInput = new Scanner(System.in); //Ask the user for a value System.out.println("Enter some monetary value"); BigDecimal numberEntered = userInput.nextBigDecimal(); //Close Scanner userInput.close(); //Print Result System.out.println("The value of numberEntered is " + numberEntered.toString()); } }
Enter some monetary value 20.20 The value of numberEntered is 20.20
Review Exercise 3.1: Sales Tax
Instructions:Create a simple program using BigDecimals that calculates a sales tax of 6% and prints out the total.Suggested Methodology:
- Create a Scanner to retrieve user input as a BigDecimal
- Create a BigDecimal with value 0.06 for multiplying with total to calculate taxes
- Create an additional taxes BigDecimal and total BigDecimal to store the tax amount and the total.
- Use the .setScale method to set the rounding scale to 2 on each of the BigDecimals.
- Use the BigDecimal methods to calculate the taxes and totals
- Print out the results
Please enter item price: 100.00 Item Price: $100.00 Sales Tax: $6.00 Total Price: $106.00View Solution
0 comments:
Post a Comment