# Floating-Point Numbers and Type double

In our next application, we depart temporarily from our GradeBook case study to declare a class called Account that maintains the balance of a bank account. Most account balances are not whole numbers (e.g., 0, 22 and 1024). For this reason, class Account represents the account balance as a floating-point number (i.e., a number with a decimal point, such as 7.33, 0.0975 or 1000.12345). Java provides two primitive types for storing floating-point numbers in memoryfloat and double. The primary difference between them is that double variables can store numbers with larger magnitude and finer detail (i.e., more digits to the right of the decimal pointalso known as the number's precision) than float variables.

Floating-Point Number Precision and Memory Requirements

Variables of type float represent single-precision floating-point numbers and have seven significant digits. Variables of type double represent double-precision floating-point numbers. These require twice as much memory as float variables and provide 15 significant digitsapproximately double the precision of float variables. For the range of values required by most programs, variables of type float should suffice, but you can use double to "play it safe." In some applications, even variables of type double will be inadequatesuch applications are beyond the scope of this book. Most programmers represent floating-point numbers with type double. In fact, Java treats all floating-point numbers you type in a program's source code (such as 7.33 and 0.0975) as double values by default. Such values in the source code are known as floating-point literals. See Appendix D, Primitive Types, for the ranges of values for floats and doubles.

Although floating-point numbers are not always 100% precise, they have numerous applications. For example, when we speak of a "normal" body temperature of 98.6, we do not need to be precise to a large number of digits. When we read the temperature on a thermometer as 98.6, it may actually be 98.5999473210643. Calling this number simply 98.6 is fine for most applications involving body temperatures. Due to the imprecise nature of floating-point numbers, type double is preferred over type float because double variables can represent floating-point numbers more accurately. For this reason, we use type double tHRoughout the book.

Floating-point numbers also arise as a result of division. In conventional arithmetic, when we divide 10 by 3, the result is 3.3333333..., with the sequence of 3s repeating infinitely. The computer allocates only a fixed amount of space to hold such a value, so clearly the stored floating-point value can be only an approximation.

Common Programming Error 3.4 Using floating-point numbers in a manner that assumes they are represented precisely can lead to logic errors.

Account Class with an Instance Variable of Type double

Our next application (Fig. 3.13Fig. 3.14) contains a class named Account (Fig. 3.13) that maintains the balance of a bank account. A typical bank services many accounts, each with its own balance, so line 7 declares an instance variable named balance of type double. Variable balance is an instance variable because it is declared in the body of the class (lines 630) but outside the class's method declarations (lines 1016, 1922 and 2528). Every instance (i.e., object) of class Account contains its own copy of balance.

Figure 3.13. Account class with an instance variable of type double.

 ``` 1 // Fig. 3.13: Account.java 2 // Account class with a constructor to 3 // initialize instance variable balance. 4 5 public class Account 6 { 7 private double balance; // instance variable that stores the balance 8 9 // constructor 10 public Account( double initialBalance ) 11 { 12 // validate that initialBalance is greater than 0.0; 13 // if it is not, balance is initialized to the default value 0.0 14 if ( initialBalance > 0.0 ) 15 balance = initialBalance; 16 } // end Account constructor 17 18 // credit (add) an amount to the account 19 public void credit( double amount ) 20 { 21 balance = balance + amount; // add amount to balance 22 } // end method credit 23 24 // return the account balance 25 public double getBalance() 26 { 27 return balance; // gives the value of balance to the calling method 28 } // end method getBalance 29 30 } // end class Account ```

Figure 3.14. Inputting and outputting floating-point numbers with Account objects.

(This item is displayed on pages 102 - 103 in the print version)

``` 1 // Fig. 3.14: AccountTest.java
2 // Create and manipulate an Account object.
3 import java.util.Scanner;
4
5 public class AccountTest
6 {
7 // main method begins execution of Java application
8 public static void main( String args[] )
9 {
10 Account account1 = new Account( 50.00 ); // create Account object
11 Account account2 = new Account( -7.53 ); // create Account object
12
13 // display initial balance of each object
14 System.out.printf( "account1 balance:\$%.2f
",
15 account1.getBalance() );
16 System.out.printf( "account2 balance:\$%.2f

",
17 account2.getBalance() );
18
19 // create Scanner to obtain input from command window
20 Scanner input = new Scanner( System.in );
21 double depositAmount; // deposit amount read from user
22
23 System.out.print( "Enter deposit amount for account1: " ); // prompt
24 depositAmount = input.nextDouble(); // obtain user input
25 System.out.printf( "

",
26 depositAmount );
27 account1.credit( depositAmount ); // add to account1 balance
28
29 // display balances
30 System.out.printf( "account1 balance:\$%.2f
",
31 account1.getBalance() );
32 System.out.printf( "account2 balance:\$%.2f

",
33 account2.getBalance() );
34
35 System.out.print( "Enter deposit amount for account2: " ); // prompt
36 depositAmount = input.nextDouble(); // obtain user input
37 System.out.printf( "

",
38 depositAmount );
39 account2.credit( depositAmount ); // add to account2 balance
40
41 // display balances
42 System.out.printf( "account1 balance:\$%.2f
",
43 account1.getBalance() );
44 System.out.printf( "account2 balance:\$%.2f
",
45 account2.getBalance() );
46 } // end main
47
48 } // end class AccountTest
```

 ```account1 balance: \$50.00 account2 balance: \$0.00 Enter deposit amount for account1: 25.53 adding 25.53 to account1 balance account1 balance: \$75.53 account2 balance: \$0.00 Enter deposit amount for account2: 123.45 adding 123.45 to account2 balance account1 balance: \$75.53 account2 balance: \$123.45 ```

Class Account contains a constructor and two methods. Since it is common for someone opening an account to place money in the account immediately, the constructor (lines 1016) receives a parameter initialBalance of type double that represents the account's starting balance. Lines 1415 ensure that initialBalance is greater than 0.0. If so, initialBalance's value is assigned to instance variable balance. Otherwise, balance remains at 0.0its default initial value.

Method credit (lines 1922) does not return any data when it completes its task, so its return type is void. The method receives one parameter named amounta double value that will be added to the balance. Line 21 adds amount to the current value of balance, then assigns the result to balance (thus replacing the prior balance amount).

Method getBalance (lines 2528) allows clients of the class (i.e., other classes that use this class) to obtain the value of a particular Account object's balance. The method specifies return type double and an empty parameter list.

Once again, note that the statements at lines 15, 21 and 27 use instance variable balance even though it was not declared in any of the methods. We can use balance in these methods because it is an instance variable of the class.

AccountTest Class to Use Class Account

Class AccountTest (Fig. 3.14) creates two Account objects (lines 1011) and initializes them with 50.00 and -7.53, respectively. Lines 1417 output the balance in each Account by calling the Account's getBalance method. When method getBalance is called for account1 from line 15, the value of account1's balance is returned from line 27 of Fig. 3.13 and displayed by the System.out.printf statement (Fig. 3.14, lines 1415). Similarly, when method getBalance is called for account2 from line 17, the value of the account2's balance is returned from line 27 of Fig. 3.13 and displayed by the System.out.printf statement (Fig. 3.14, lines 1617). Note that the balance of account2 is 0.00 because the constructor ensured that the account could not begin with a negative balance. The value is output by printf with the format specifier %.2f. The format specifier %f is used to output values of type float or double. The .2 between % and f represents the number of decimal places (2) that should be output to the right of the decimal point in the floating-point numberalso known as the number's precision. Any floating point value output with %.2f will be rounded to the hundredths positionfor example, 123.457 would be rounded to 123.46, and 27.333 would be rounded to 27.33.

Line 20 creates a Scanner that will be used to obtain deposit amounts from a user. Line 21 declares local variable depositAmount to store each deposit amount entered by the user. Unlike the instance variable balance in class Account, local variable depositAmount in main is not initialized to 0.0 by default. However, this variable does not need to be initialized here because its value will be determined by the user's input.

Line 23 prompts the user to enter a deposit amount for account1. Line 24 obtains the input from the user by calling Scanner object input's nextDouble method, which returns a double value entered by the user. Lines 2526 display the deposit amount. Line 27 calls object account1's credit method and supplies depositAmount as the method's argument. When the method is called, the argument's value is assigned to parameter amount (line 19 of Fig. 3.13) of method credit (lines 1922 of Fig. 3.13), then method credit adds that value to the balance (line 21 of Fig. 3.13). Lines 3033 (Fig. 3.14) output the balances of both Accounts again to show that only account1's balance changed.

Line 35 prompts the user to enter a deposit amount for account2. Line 36 obtains the input from the user by calling Scanner object input's nexTDouble method. Lines 3738 display the deposit amount. Line 39 calls object account2's credit method and supplies depositAmount as the method's argument, then method credit adds that value to the balance. Finally, lines 4245 output the balances of both Accounts again to show that only account2's balance changed.

UML Class Diagram for Class Account

The UML class diagram in Fig. 3.15 models class Account of Fig. 3.13. The diagram models the private attribute balance of UML type Double to correspond to the class's instance variable balance of Java type double. The diagram models class Account's constructor with a parameter initialBalance of UML type Double in the third compartment of the class. The class's two public methods are modeled as operations in the third compartment as well. The diagram models operation credit with an amount parameter of UML type Double (because the corresponding method has an amount parameter of Java type double) and operation getBalance with a return type of Double (because the corresponding Java method returns a double value).

Figure 3.15. UML class diagram indicating that class Account has a private balance attribute of UML type Double, a constructor (with a parameter of UML type Double) and two public operationscredit (with an amount parameter of UML type Double) and getBalance (returns UML type Double).  Java How to Program (6th Edition) (How to Program (Deitel))
ISBN: 0131483986
EAN: 2147483647
Year: 2003
Pages: 615

Similar book on Amazon 