Performing Calculations in C#

Our “Hello, World” program illustrated the basic structure of a C# program and introduced classes and components, but we need a slightly more elaborate example to show the use of other basic programming constructs, such as variables, expressions, and control structures. Our next example is a simple calculator for a savings account. The user is prompted for annual contribution, interest rate, and number of years. We calculate the accumulation of deposits two ways:

  • In a loop, year by year, accumulating a total as we go

  • Using a formula

The example program is in the folder Savings.


// Savings.cs

using System;

class Savings
{
   public static void Main(string[] args)
   {
      InputWrapper iw = new InputWrapper();
      decimal amount;   // annual deposit amount
      decimal rate;     // interest rate
      int years;        // number of years
      decimal total;    // total accumulation
      decimal interest; // interest in a year
      Console.Write("amount: ");
      string data = Console.ReadLine();
      amount = Convert.ToDecimal(data);
      rate = iw.getDecimal("rate: ");
      years = iw.getInt("years: ");
      total = 0m;
      Console.WriteLine("{0,4} {1,12} {2,12} {3,12}",
         "Year", "Amount", "Interest", "Total");
      for (int i = 1; i <= years; i++)
      {
         interest = total * rate;
         total += amount + interest;
         Console.WriteLine(
            "{0, -4} {1, 12:C} {2, 12:C} {3, 12:C}",
            i, amount, interest, total);
      }
      Console.WriteLine("
Total using formula = {0}",
         Total(years, (double) rate, (double) amount));
   }
   private static double Total(int years, double rate,
      double amount)
   {
      double total =
         amount * (Math.Pow(1 + rate, years) - 1) / rate;
      long total_in_cents = (long) Math.Round(total * 100);
      total = total_in_cents /100.0;
      return total;
   }
}

If you compile and run it, you will see this output:

amount: 1000
rate: .05
years: 10
Year       Amount     Interest        Total
1       $1,000.00        $0.00    $1,000.00
2       $1,000.00       $50.00    $2,050.00
3       $1,000.00      $102.50    $3,152.50
4       $1,000.00      $157.63    $4,310.13
5       $1,000.00      $215.51    $5,525.63
6       $1,000.00      $276.28    $6,801.91
7       $1,000.00      $340.10    $8,142.01
8       $1,000.00      $407.10    $9,549.11
9       $1,000.00      $477.46   $11,026.56
10      $1,000.00      $551.33   $12,577.89

Variables

In C# variables are of a specific data type. Some common types are int for integers and double for floating-point numbers. C# has the decimal data type, which has a high degree of precision, suitable for monetary calculations.

You must declare and initialize variables before you can use them.

int years = 10;       // reserves space and assigns
                      // an initial value
decimal interest;     // reserves space but does
                      // not initialize it to any value

If an initial value is not specified in the declaration, the variable must be initialized in code before it can be used. We discuss initialization later in the appendix.

Variables must be either local within a method or members of a class. There are no global variables in C#.

Literals

A literal is used when you explicitly write a value for a variable in a program. An integer literal is represented by either an ordinary decimal integer or a hexadecimal integer. A floating-point or decimal literal is represented by a number with a decimal point or by exponential notation. You may influence the type that is used for storing a literal by a suffix. The suffix f or F indicates single precision floating point. The suffix d or D indicates double-precision floating point. The suffix m or M indicates decimal (think money).

decimal rate = 0.06m;
decimal amount = 2000M;

There are two forms for string literals. Escape sequences are not processed for string literals that are prefixed with @.

string file1 ="c:\test1.txt";
string file2 = @"c:	est2.txt";

C# Operators and Expressions

You can combine variables and literals via operators to form expressions. The C# operators are similar to those in C and C++, having similar precedence and associativity rules. There are three kinds of operators:

  • Unary operators take one operand and use prefix notation (e.g., –a) or postfix notation (e.g., a++).

  • Binary operators take two operands and use infix notation (e.g., a + b).

  • The one ternary operator ?: takes three operands and uses infix notation (e.g., expr ? x : y).

Operators are applied in the precedence order shown in Table B-1. For operators of the same precedence, order is determined by associativity.

  • The assignment operator is right-associative (operations are performed from right to left).

  • All other binary operators are left-associative (operations are performed from left to right).

Precedence and associativity can be controlled by parentheses; what is done first is shown as the primary operator (x) in the precedence table.

Table B-1. Operator Precedence in C#
CategoryOperators
Primary(x) x.y f(x) a[x] x++ x-- new typeof sizeof checked unchecked
Unary+ - ! ~ ++x --x (T)x
Multiplicative* / %
Additive+ -
Shift<< >>
Relational< > <= >= is as
Equality== !=
Logical AND&
Logical XOR^
Logical OR|
Conditional AND&&
Conditional OR||
Conditional?:
Assignment= *= /= %= += -= <<= >>= &= ^= |=

Output and Formatting

The Console class in the System namespace supports two simple methods for performing output:

  • WriteLine writes out a string followed by a new line.

  • Write writes out just the string without the new line.

You can write out other data types by relying on the ToString method of System.Object, which will provide a string representation of any data type. We discussed the root class System.Object in Chapter 13, where we also saw how to override ToString for your own custom data type. You can use the string concatenation operator + to build up an output string.

int x = 24;
int y = 5;
int z = x * y;
Console.Write("Product of " + x + " and " + y);
						Console.WriteLine(" is " + z);
					

The output is all on one line:

Product of 24 and 5 is 120

PLACEHOLDERS

A more convenient way to build up an output string is to use placeholders: {0}, {1}, and so on. An equivalent way to do the output shown above is


Console.WriteLine("Product of {0} and {1} is {2}", x,y,z);

The program OutputDemo illustrates the output operations just discussed.

We will generally use placeholders for our output from now on. Placeholders can be combined with formatting characters to control output format.

FORMAT STRINGS

C# has extensive formatting capabilities, which you can control through placeholders and format strings.

  • Simple placeholders: {n}, where n is 0, 1, 2, … , indicating which variable to insert

  • Control width: {n,w}, where w is the width (positive for right justified and negative for left justified) of the inserted variable

  • Format string: {n:S}, where S is a format string indicating how to display the variable

  • Width and format string: {n,w:S}

A format string consists of a format character followed by an optional precision specifier. Table B-2 shows the available format characters. (These format characters are defined in the .NET Framework, and thus can be used in other .NET languages, including PerlNET.)

Table B-2. .NET Format Characters
Format CharacterMeaning
CCurrency (locale specific)
DDecimal integer
EExponential (scientific)
FFixed point
GGeneral (E or F)
NNumber with embedded commas
XHexadecimal

SAMPLE FORMATTING CODE

Our sample program Savings provides an illustration. The header uses width specifiers, and the output inside the loop uses width specifiers and the currency format character.

...
Console.WriteLine("{0,4} {1,12} {2,12} {3,12}",
   "Year", "Amount", "Interest", "Total");
for (int i = 1; i <= years; i++)
{
   interest = total * rate;
   total += amount + interest;
   Console.WriteLine(
      "{0, -4} {1, 12:C} {2, 12:C} {3, 12:C}",
      i, amount, interest, total);
}
...

Control Structures

The preceding code fragment illustrates a for loop. The C# control structures include the familiar control structures of the C family of languages,

  • if

  • while

  • do

  • for

  • switch

  • break

  • continue

  • return

  • goto

These all have standard semantics, except for switch, which is less error prone in C#. There are several other control statements in C#:

  • There is a foreach loop, which we discuss later in connection with arrays and collections.

  • The throw statement is used with exceptions. We discuss exceptions later in this appendix.

  • The lock statement can be used to enforce synchronization in multithreading situations.

SWITCH STATEMENT

In C#, after a particular case statement is executed, control does not automatically continue to the next statement. You must explicitly specify the next statement, typically by a break or goto label. (As in C and C++, you may call for identical handling of several cases by having empty statements for all the case labels except the last one.) In C# you may also switch on a string data type. The program SwitchDemo illustrates use of the switch statement in C#.


...
switch(scores[i])
{
   case 1:
      Console.Write("Very ");
      goto case 2;  // cannot fall through
							case 2:
      Console.WriteLine("Low");
      break;
   case 3:
      Console.WriteLine("Medium");
      break;
   case 4:
							case 5:
      Console.WriteLine("High");
      break;
   default:
      Console.WriteLine("Special Case");
      break;
  }
...

Methods

Our Savings example program has a method Total for computing the total accumulation by use of a formula. In C# every function is a method of some class; there are no freestanding functions. If the method does not refer to any instance variables of the class, the method can be static. We discuss instance data of a class later in this appendix. Since the method is accessed only from within the class, it is designated as private.

Note the use of the Pow and Round methods of the Math class, which is another class in the System namespace. These methods are static methods. To call a static method from outside the class in which it is defined, place the name of the class followed by a period before the method name. In C# you cannot employ the alternative C++ style of using an instance name to qualify a static method.

...
private static double Total(int years, double rate,
   double amount)
{
   double total[2] = 
      amount * (Math.Pow(1 + rate, years) - 1) / rate;
   long total_in_cents = (long) Math.Round(total * 100);
   total = total_in_cents /100.0;
   return total;
}
...

[2] Note that identifiers in C# are case-sensitive, so the variable total is different from the method Total. Such usage is not recommended but is permissible.

Console Input in C#

An easy, uniform way to do input for various data types is to read the data as a string and then convert to the desired data type. Use the ReadLine method of the System.Console class to read in a string. Use the ToXxxx methods of the System.Convert class to convert the data to the type you need.

Console.Write("amount: ");
string data = Console.ReadLine();
amount = Convert.ToDecimal(data);

Although console input in C# is fairly simple, we can make it even easier using object-oriented programming. We can encapsulate the details of input in an easy-to-use wrapper class, InputWrapper (which is not part of the .NET Framework class library).

USING THE INPUTWRAPPER CLASS

In C# you instantiate a class by using the new keyword.

InputWrapper iw = new InputWrapper();

This code creates the object instance iw of the InputWrapper class.

The InputWrapper class wraps interactive input for several basic data types. The supported data types are int, double, decimal, and string. Methods getInt, getDouble, getDecimal, and getString are provided to read those types from the command line. A prompt string is passed as an input parameter. For convenience, we provide the file InputWrapper.cs in each project where we use it.

You can use the InputWrapper class without knowing its implementation. With such encapsulation, complex functionality can be hidden by an easy-to-use interface.

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

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