Introduction
When you study a .NET language like C#, you soon find out that there are many types of APIs that facilitate certain operations - mathematics, file I/O, thread synchronization, networking, and so forth - and thus reduce the complications that come with building an actually practical Windows application. This article will focus on building a practical Windows Forms application by using certain Math APIs that are defined in the Framework Class Library. Prior to stepping through the process of building such an application, however, this article will begin by describing some of these APIs, special characters, and numeric specifiers by using sample code. If the downloadable application does not appear to have any practical usage, it could function as a skeleton application on which to expand on or help the user to create something similar which does have practical use.
A basic math API which is used to raise one number to the power of another can be written as:
public static class Math {
public static extern double Pow (double x, double y);
...
}
Now, here is a very basic program that raises the number 16 to the 2nd power:
using System;
public class Application {
public static void Main() {
Console.WriteLine("Pow({0}, {1}) = {2}", 16, 2, Math.Pow(16, 2));
}
}
Here is the output:
Pow(16, 2) = 256
Characters and Escape Sequences
In the .NET Framework, characters are always represented by 16-bit Unicode values. A character is represented with an instance of the System.Char
structure (a value type) that offers two public read-only constant fields: MinValue
is defined as '\0', and MaxValue
is defined as '\uffff'. There is also a set of escape sequences that may be used to represent characters that are difficult to represent literally. For instance, when you hit the return key, your cursor drops down one line and then moves to the far left. This is called a carriage return line feed, and is often known as 0x0D and 0x0A, respectively. So, when you build a Windows application that is going to perform an operation and display the results in a multiline text box, these escape sequences play a part in the string formatting and their line placement:
- \' \u0027 (39) Single Quotation Mark
- \" \u0022 (34) Double Quotation Mark
- \\ \u005C (92) Backslash
- \0 \u0000 (0) Null
- \a \u0007 (7) Bell
- \b \u0008 (8) Backspace
- \t \u0009 (9) Tab
- \v \u000B (11) Vertical tab
- \f \u000C (12) Form feed
- \n \u000A (10) New line
- \r \u000D (13) Carriage return
Below is a code snippet showing the use of some of these escape sequences:
using System;
public class Program {
public static void Main() {
Console.WriteLine("Alert \\a: {0} ({1})", '\a', (int)'\a');
Console.WriteLine("Backspace \\b: {0} ({1})", '\b', (int)'\b');
Console.WriteLine("Horizontal tab \\t: {0} ({1})", '\t', (int)'\t');
Console.WriteLine("Newline \\r: {0} ({1})", '\r', (int)'\r');
Console.WriteLine("Vertical quote \\v: {0} ({1})", '\v', (int)'\v');
Console.WriteLine("Form feed \\f: {0} ({1})", '\f', (int)'\f');
Console.WriteLine("Carriage return \\r: {0} ({1})", '\r', (int)'\r');
}
}
This outputs like this:
Alert \a: (7)
Backspace \b: (8)
Horizontal tab \t: (9)
(13)ne \r:
Vertical quote \v: ♂‚ (11)
Form feed \f: ♀ (12)
(13)age return \r:
So, what is the point of showing a number raised to a power and a bunch of technical details about .NET Framework characters? Well, they are going to a pivotal role now that we can build an application. This application requires a Windows Form that has three Label
s, two regular TextBox
es for user input, a NumericUpDown
control, and a third multiline text box with a vertical scroll bar. The NumericUpDown
control is nearly the same as the DomainUpDown
with the restriction that its contents are numeric. Finally, a Button
control is going to take two user input fields, principal and interest, and calculate the amount of the yearly account balance having earned that interest. The NumericUpDown
control increments by one each time: so if you click from 1 to 2, you will get a second line of output with interest earned in the second line of the multiline text box. The NumericUpDown
control's Minimum
property is set to 1 and its Maximum
property is set to 10. Its Increment
property is set to 1 and its read-only property is set to true
. The AutoSize
property of all of the Label
s is set to false
to enable a clear 16 pt font using Times New Roman. Here is a look at the application without using it to calculate any interest earned:
And, here is a look at the interest earned for four years. The reader should take care to note that the interest earned appears as compound interest. The first year's amount of $10,000 at 36% interest simply earns $10,036. The second year's balance comes to $10,072.13, or $36 dollars and 13 cents more. Compounded interest would earn 36% on the $10,036, and not just add $36.00 to each year:
Here is the code this application placed in one file, in order to compile it on the DOS prompt. In the directory "C:\Windows\Microsoft.NET\Framework\v2.0.50727", just type 'type con > Thefile.cs'. The cursor will drop to a blank screen where there is no prompt. Copy and paste the code onto the blank DOS windows, and compile the code with the '/target:winexe' switch:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
public partial class Form1 : Form
{
private System.Windows.Forms.Button calculateButton;
private System.Windows.Forms.TextBox principalTextBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox interestTextBox;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.NumericUpDown yearUpDown;
private System.Windows.Forms.TextBox displayTextBox;
private System.Windows.Forms.VScrollBar vScrollBar1;
private System.Windows.Forms.Label label3;
public Form1()
{
InitializeComponent();
}
private void InitializeComponent() {
this.calculateButton = new System.Windows.Forms.Button();
this.principalTextBox = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.interestTextBox = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.yearUpDown = new System.Windows.Forms.NumericUpDown();
this.displayTextBox = new System.Windows.Forms.TextBox();
this.vScrollBar1 = new System.Windows.Forms.VScrollBar();
this.label3 = new System.Windows.Forms.Label();
this.SuspendLayout();
this.calculateButton.Font =
new System.Drawing.Font("Times New Roman", 14.25F,
System.Drawing.FontStyle.Bold,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.calculateButton.Location = new System.Drawing.Point(310, 30);
this.calculateButton.Name = "calculateButton";
this.calculateButton.Size = new System.Drawing.Size(103, 33);
this.calculateButton.TabIndex = 0;
this.calculateButton.Text = "Calculate";
this.calculateButton.UseVisualStyleBackColor = true;
this.calculateButton.Click +=
new System.EventHandler(this.calculateButton_Click);
this.principalTextBox.Location = new System.Drawing.Point(152, 30);
this.principalTextBox.Name = "principalTextBox";
this.principalTextBox.Size = new System.Drawing.Size(133, 20);
this.principalTextBox.TabIndex = 1;
this.label1.Font =
new System.Drawing.Font("Times New Roman", 15.75F,
((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold |
System.Drawing.FontStyle.Italic))),
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.Location = new System.Drawing.Point(14, 33);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(100, 23);
this.label1.TabIndex = 2;
this.label1.Text = "Principal";
this.interestTextBox.Location = new System.Drawing.Point(152, 105);
this.interestTextBox.Name = "interestTextBox";
this.interestTextBox.Size = new System.Drawing.Size(133, 20);
this.interestTextBox.TabIndex = 3;
this.label2.Font =
new System.Drawing.Font("Times New Roman",
15.75F, System.Drawing.FontStyle.Bold,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.Location = new System.Drawing.Point(18, 105);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(100, 23);
this.label2.TabIndex = 4;
this.label2.Text = "Interest";
this.yearUpDown.Location = new System.Drawing.Point(267, 178);
this.yearUpDown.Maximum =
new decimal(new int[] {
10,
0,
0,
0});
this.yearUpDown.Minimum =
new decimal(new int[] {
1,
0,
0,
0});
this.yearUpDown.Name = "yearUpDown";
this.yearUpDown.ReadOnly = true;
this.yearUpDown.Size = new System.Drawing.Size(37, 20);
this.yearUpDown.TabIndex = 5;
this.yearUpDown.Value =
new decimal(new int[] {
1,
0,
0,
0});
this.displayTextBox.Location = new System.Drawing.Point(70, 298);
this.displayTextBox.Multiline = true;
this.displayTextBox.Name = "displayTextBox";
this.displayTextBox.Size = new System.Drawing.Size(300, 120);
this.displayTextBox.TabIndex = 6;
this.vScrollBar1.Location = new System.Drawing.Point(353, 298);
this.vScrollBar1.Name = "vScrollBar1";
this.vScrollBar1.Size = new System.Drawing.Size(17, 120);
this.vScrollBar1.TabIndex = 7;
this.label3.Font =
new System.Drawing.Font("Times New Roman", 12F,
System.Drawing.FontStyle.Bold,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label3.Location = new System.Drawing.Point(70, 238);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(189, 23);
this.label3.TabIndex = 8;
this.label3.Text = "Your Account Balance is:";
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor =
System.Drawing.Color.FromArgb(((int)(((byte)(0)))),
((int)(((byte)(192)))), ((int)(((byte)(0)))));
this.ClientSize = new System.Drawing.Size(427, 451);
this.Controls.Add(this.label3);
this.Controls.Add(this.vScrollBar1);
this.Controls.Add(this.displayTextBox);
this.Controls.Add(this.yearUpDown);
this.Controls.Add(this.label2);
this.Controls.Add(this.interestTextBox);
this.Controls.Add(this.label1);
this.Controls.Add(this.principalTextBox);
this.Controls.Add(this.calculateButton);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();
}
[System.STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
private void calculateButton_Click(object sender, EventArgs e)
{
decimal principal;
double rate;
int year;
decimal amount;
string output;
principal = Convert.ToDecimal(principalTextBox.Text);
rate = Convert.ToDouble(interestTextBox.Text);
year = Convert.ToInt32(yearUpDown.Value);
output = "year\tAmount on Deposit\r\n";
for (int yearCounter = 1; yearCounter <= year; yearCounter++)
{
amount = principal * ( ( decimal)
Math.Pow(( 1 + rate / 100), yearCounter));
output += (yearCounter + "\t" +
string.Format( "{0:C}", amount) +
"\r\n" );
}
displayTextBox.Text = output;
}
}
Notice the event handler of the Button
control. We first declare the data types that are represented by the first two Label
s and the other necessary variables for the calculation. The output is considered a string
type in order to format the calculation using the tab, carriage return, and new line escape sequences. The delimiter "{0:C}" stands for currency. So these variables get converted into numeric data types to then have the Name
s (property) of the first two TextBox
es and the NumericUpDown
controls passed as parameters. They are then used within a for
loop to iterate the years counted, incrementing each year by one. Afterwards, the string
data type "amount" is calculated using the Math Power API to finally output the results in the multiline text box, whose Name
is set to that output.
The reason the .NET Framework uses the 16-bit Unicode encoding scheme is to ease the complications involved with global development. C is a specifier that formats a string using the culture-aware currency attributes, such as symbols (money, separator) and significant number of digits.
References
- Professional .NET Framework 2.0 by Joe Duffy
- CLR via C# by Jeffrey Richter