6.6 App: Compound-Interest Calculations

The next app uses the for statement to compute compound interest. Consider the following problem:

  • A person invests $1,000 in a savings account yielding 5% interest. Assuming that all the interest is left on deposit, calculate and print the amount of money in the account at the end of each year for 10 years. Use the following formula to determine the amounts:

    a=p (1+r)n

    where

    • p is the original amount invested (i.e., the principal)

    • r is the annual interest rate (e.g., use 0.05 for 5%)

    • n is the number of years

    • a is the amount on deposit at the end of the nth year.

The solution to this problem (Fig. 6.6) involves a loop that performs the indicated calculation for each of the 10 years the money remains on deposit.

Fig. 6.6 Compound-interest calculations with for.

Alternate View

  1    // Fig. 6.6: Interest.cs
  2    // Compound-interest calculations with for.
  3    using System;
  4
  5    class Interest
  6    {
  7         static void Main()
  8         {
  9            decimal principal = 1000; // initial amount before interest
 10            double rate = 0.05; // interest rate
 11
 12             // display headers
 13             Console.WriteLine("Year  Amount on deposit");
 14
 15             // calculate amount on deposit for each of ten years
 16             for (int year = 1; year <= 10; ++year)
 17             {
 18                // calculate new amount for specified year
 19                decimal amount = principal *              
 20                   ((decimal) Math.Pow(1.0 + rate, year));
 21
 22                 // display the year and the amount
 23                 Console.WriteLine($"{year,4}{amount,20:C}");
 24             }
 25         }
 26    }

  Year      Amount on deposit
     1              $1,050.00
     2              $1,102.50
     3              $1,157.63
     4              $1,215.51
     5              $1,276.28
     6              $1,340.10
     7              $1,407.10
     8              $1,477.46
     9              $1,551.33
    10              $1,628.89

Lines 9 and 19 declare decimal variables principal and amount, and line 10 declares double variable rate. Lines 9–10 also initialize principal to 1000 (i.e., $1,000.00) and rate to 0.05. C# treats numeric literals like 0.05 as type double. Similarly, C# treats whole-number literals like 7 and 1000 as type int—unlike double values, int values can be assigned to decimal variables. When principal is initialized to 1000, the int value 1000 is promoted to type decimal implicitly—no cast is required. Line 13 outputs the headers for the app’s two columns of output. The first column displays the year, and the second displays the amount on deposit at the end of that year.

6.6.1 Performing the Interest Calculations with Math Method pow

Classes provide methods that perform common tasks on objects. Most methods must be called on a specific object. For example, to deposit money into bank accounts in Fig. 4.12, we called method Deposit on the Account objects account1 and account2. Many classes also provide methods to perform common tasks that do not require specific objects—they must be called using a class name. Such methods are called static methods. You’ve used several static methods of class Console —methods Write, WriteLine and ReadLine. You call a static method by specifying the class name followed by the member-access operator (.) and the method name, as in


ClassName.MethodName(arguments)

C# does not include an exponentiation operator, so we use class Math’s static method Pow to perform the compound-interest calculation. The expression


Math.Pow(x, y)

calculates the value of x raised to the yth power. The method receives two double arguments and returns a double value. Lines 19–20 in Fig. 6.6 perform the calculation


a = p (1 + r)n

from the problem statement, where a is the amount, p is the principal, r is the rate and n is the year. In this calculation, we need to multiply the decimal value principal by a double value (the value returned by the call to Math.Pow). C# will not implicitly convert double to a decimal type, or vice versa, because of the possible loss of information in either conversion, so line 20 contains a (decimal) cast operator that explicitly converts Math.Pow’s double return value to a decimal.

The for statement’s body contains the calculation 1.0 + rate, which appears as an argument to the Math.Pow method. In fact, this calculation produces the same result each time through the loop, so repeating the calculation in every iteration of the loop is wasteful.

Performance Tip 6.2

In loops, avoid calculations for which the result never changes—such calculations should typically be placed before the loop. Optimizing compilers will typically do this for you.

6.6.2 Formatting with Field Widths and Alignment

After each calculation, line 23


Console.WriteLine($"{year,4}{amount,20:C}");

displays the year and the amount on deposit at the end of that year. The interpolation expression


{year,4}

formats the year. The integer 4 after the comma indicates that the value output should be displayed with a field width of 4—that is, WriteLine displays the value with at least four character positions. If the value to be output is fewer than four character positions wide (one or two characters in this example), the value is right-aligned in the field by default— in this case the value is preceded by two or three spaces, depending on the year value. If the value to be output were more than four character positions wide, the field width would be extended to the right to accommodate the entire value—this would push the amount column to the right, upsetting the neat columns of our tabular output. Similarly, the interpolation expression


{amount,20:C}

formats the amount as currency (C) right-aligned in a field of at least 20 characters. To left align a value, simply use a negative field width.

6.6.3 Caution: Do Not Use float or double for Monetary Amounts

Section 4.9 introduced the simple type decimal for precise monetary representation and calculations. You might be tempted to use the floating-point types float or double for such calculations. However, for certain values types float or double suffer from what we call representational error. For example, floating-point numbers often arise as a result of calculations—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 6.5

Using floating-point numbers in a manner that assumes they’re represented exactly (e.g., using them in comparisons for equality) can lead to incorrect results. Floating-point numbers are represented only approximately.

Error-Prevention Tip 6.5

Do not use variables of type double (or float) to perform precise monetary calculations— use type decimal instead. The imprecision of floating-point numbers can cause errors that will result in incorrect monetary values.

Applications of Floating-Point Numbers

Floating-point numbers have numerous applications, especially for measured values. For example, when we speak of a “normal” body temperature of 98.6 degrees Fahrenheit, we need not 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. Similarly, we used type double to perform class-average calculations in Chapter 5. 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 precisely. For this reason, we use type double throughout the book, unless we’re manipulating monetary amounts, in which case we use type decimal.

A Warning About Displaying Rounded Values

Two double dollar amounts stored in the machine could be 14.234 (which would normally be rounded to 14.23 for display purposes) and 18.673 (which would normally be rounded to 18.67 for display purposes). When these amounts are added, they produce the internal sum 32.907, which would normally be rounded to 32.91 for display purposes. Thus, your output could appear as


  14.23
+ 18.67
-------
  32.91

but a person adding the individual numbers as displayed would expect the sum to be 32.90. You’ve been warned! For people who work with programming languages that do not support a type like decimal for precise monetary calculations, Exercise 6.18 explores the use of integers to perform such calculations.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset