Performing Calculations in C

for RuBoard

Performing Calculations in C#

Our "Hello, World" program illustrated the basic structure of a C# program, but we will 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 an IRA account. We calculate the accumulation of deposits to an IRA of $2000.00 a year at 6% interest for 10 years , assuming that each deposit is made at the end of the year. Our calculation is performed two ways:

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

  • Using a formula

The example program is in the folder Ira\Step1.

 // Ira.cs - Step 1  using System;  class Ira  {     public static int Main(string[] args)     {        int years = 10;        decimal rate = 0.06m;        decimal amount = 2000M;        decimal interest;        decimal 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("\nTotal using formula = {0}",           IraTotal(years, (double) rate, (double) amount));        return 0;     }     public static double IraTotal(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:

 Year       Amount     Interest        Total  1       ,000.00 
 Year Amount Interest Total 1 $2,000.00 $0.00 $2,000.00 2 $2,000.00 $120.00 $4,120.00 3 $2,000.00 $247.20 $6,367.20 4 $2,000.00 $382.03 $8,749.23 5 $2,000.00 $524.95 $11,274.19 6 $2,000.00 $676.45 $13,950.64 7 $2,000.00 $837.04 $16,787.68 8 $2,000.00 $1,007.26 $19,794.94 9 $2,000.00 $1,187.70 $22,982.63 10 $2,000.00 $1,378.96 $26,361.59 Total using formula = 26361.59 
.00 ,000.00 2 ,000.00 0.00 ,120.00 3 ,000.00 7.20 ,367.20 4 ,000.00 2.03 ,749.23 5 ,000.00 4.95 ,274.19 6 ,000.00 6.45 ,950.64 7 ,000.00 7.04 ,787.68 8 ,000.00 ,007.26 ,794.94 9 ,000.00 ,187.70 ,982.63 10 ,000.00 ,378.96 ,361.59 Total using formula = 26361.59

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 will discuss initialization later in the chapter.

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 [1] 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).

[1] We discuss C# types, such as float , double , and decimal , later in the chapter.

 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:\test2.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 3-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. C# has checked and unchecked operators, which will be discussed later.

Table 3-1. Operator Precedence in C#

Category

Operators

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 will discuss the root class System.Object in Chapter 5, where you will also see 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 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 3-2 shows the available format characters.

Table 3-2. C# Format Characters

Format Character

Meaning

C

Currency (locale specific)

D

Decimal integer

E

Exponential (scientific)

F

Fixed point

G

General (E or F)

N

Number with embedded commas

X

Hexadecimal

Sample Formatting Code

The program FormatDemo illustrates formatting. Our sample program Ira\Step1 provides another example. 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 will discuss later in connection with arrays and collections.

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

  • The lock statement can be used to enforce synchronization in multithreading situations. We will discuss multithreading in Chapter 8.

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 Ira\Step1 example program has a method IraTotal for computing the total IRA 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 will discuss instance data of a class later in this chapter. 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 IraTotal(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;  }  ... 

Console Input in C#

Our first Ira program is not too useful, because the data are hardcoded. To perform the calculation for different data, you would have to edit the source file and recompile. What we really want to do is allow the user of the program to enter the data at runtime.

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. The directory InputWrapper contains the files InputWrapper.cs , which implements the class, and TestInputWrapper.cs , which tests the class. (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. (A listing of the InputWrapper class is in the next section.)

Here is the code for Ira\Step2 . We read in the deposit amount, the interest rate, and the number of years, and we compute the IRA accumulation year by year. The first input is done directly, and then we use the InputWrapper class. The bolded code illustrates how to use the InputWrapper class. Instantiate an InputWrapper object iw by using new . Prompt for and obtain input data by calling the appropriate getXXX method.

 // Ira.cs - Step 2  using System;  class Ira  {     public static int 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("\nTotal using formula = {0}",           IraTotal(years, (double) rate, (double) amount));        return 0;     }     private static double IraTotal(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;     }  } 
Compiling Multiple Files

The program in Ira\Step2 is our first example of the common situation of a program with multiple files (in this case, just two: Ira.cs and InputWrapper.cs ). It is easy to compile multiple files at the command line.

 > csc /out:Ira.exe *.cs 

This will compile all the files in the current directory. You should use the /out option to specify the name of the output file.

If multiple classes contain a Main method, you can use the /main command-line option to specify which class contains the Main method that you want to use as the entry point into the program.

 >csc /main:Ira /out:Ira.exe *.cs 
InputWrapper Class Implementation

The InputWrapper class is implemented in the file InputWrapper.cs . You should find the code reasonably intuitive, given what you already know about classes.

 // InputWrapper.cs  //  // Class to wrap simple stream input  // Datatype supported:  //      int  //      double  //      decimal  //      string  using System;  class InputWrapper  {     public int getInt(string prompt)     {        Console.Write(prompt);        string buf = Console.ReadLine();        return Convert.ToInt32(buf);     }     public double getDouble(string prompt)     {        Console.Write(prompt);        string buf = Console.ReadLine();        return Convert.ToDouble(buf);     }     public decimal getDecimal(string prompt)     {        Console.Write(prompt);        string buf = Console.ReadLine();        return Convert.ToDecimal(buf);     }     public string getString(string prompt)     {        Console.Write(prompt);        string buf = Console.ReadLine();        return buf;     }  } 

Note that, unlike the method IraTotal , the methods of the InputWrapper class are used outside of the class so they are marked as public .

If bad input data is presented, an exception will be thrown. Exceptions are discussed later in this chapter.

for RuBoard


Application Development Using C# and .NET
Application Development Using C# and .NET
ISBN: 013093383X
EAN: 2147483647
Year: 2001
Pages: 158

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net