In previous chapter, you learned about input in general and numeric input in particular. You also did some simple calculations on numbers entered by the user. In this chapter, you will look at numbers in more detail. After all, a computer is called a computer because it computes frequently!
Decimal Input
You will start with the task of reading a decimal number from the user.
Task
You will write program that accepts a decimal number from the user and repeats it immediately on the screen (see Figure 9-1).
Figure 9-1 The final program
Solution
There are two differences between the input of whole and decimal numbers.
You convert text input into a corresponding number by calling the Convert.ToDouble method.
To store a converted number, you use a variable of type double.
Here is the code:
static void Main(string[] args)
{
// Decimal input
Console.Write("Enter a decimal number: ");
string input = Console.ReadLine();
double decimalNumber = Convert.ToDouble(input);
// Repeating entered number to the output
Console.WriteLine("You have entered number " + decimalNumber);
// Waiting for Enter
Console.ReadLine();
}
Localized Numeric Input
In the previous exercise, the user enters a decimal separator according to the Windows language setting. This means a decimal point for the English language. However, it may mean something else in other languages. For example, a comma is used as a decimal separator in the Czech language.
In the current exercise, I will show you how to force numeric input in a specific localization, regardless of the Windows settings. You did a similar task concerning localized output earlier in the book; now you are going to concentrate on input.
Task
The task is to write a program that reads a decimal number with two fixed-language settings, American and Czech.
Solution
To work with specific localizations, use the CultureInfo object. Also, please do not forget to insert the using System.Globalization; line at the top of your source code.
Here is the code:
static void Main(string[] args)
{
// AMERICAN
CultureInfo american = new CultureInfo("en-US");
try
{
// Input
Console.Write("Enter American decimal number: ");
string input = Console.ReadLine();
double number = Convert.ToDouble(input, american);
// Output
Console.WriteLine("You have entered " + number);
}
catch (Exception)
{
// Error message
Console.WriteLine("Incorrect input");
}
// CZECH
CultureInfo czech = new CultureInfo("cs-CZ");
try
{
// Input
Console.WriteLine();
Console.Write("Enter Czech decimal number: ");
string input = Console.ReadLine();
double number = Convert.ToDouble(input, czech);
// Output
Console.WriteLine("You have entered " + number);
}
catch (Exception)
{
// Error message
Console.WriteLine("Incorrect input");
}
// Waiting for Enter
Console.ReadLine();
}
Testing and Conclusions
The following sections cover how this works.
Test with a Decimal Point
Run your program and enter a number with a decimal point twice (see Figure 9-2).
Figure 9-2 Entering two numbers with decimal points
The program accepts a point as a decimal separator when using the American localization. At the same time, it refuses a decimal point when using the Czech localization since a point is not a valid decimal separator in Czech.
Test with a Decimal Comma
Run your program again and this time enter a number with decimal comma twice (see Figure 9-3).
Figure 9-3 Entering a number twice with a comma
Now the program accepts the decimal comma as a valid separator in Czech.
When using the American localization, the program does not see any decimal number. It simply ignores the comma and converts the user input into a whole number!
Further Conclusions
In this book, I am showing the output with decimal points in the figures. This is because I have not specified any localization in the output statements, and my Windows settings are currently set to American English. Both tests show that decimal input may betray you if you are not care enough. Just to remind you, if you enter a decimal number directly in your C# source code, you should always use a decimal point regardless of your settings.
Basic Arithmetic
You are working with numbers in this chapter, so it is a good time to perform all four basic arithmetic operations .
Task
You will write a program that accepts two decimal numbers from the user and displays the results of their addition, subtraction, multiplication, and division (see Figure 9-4).
Figure 9-4 Doing basic arithmetic
Solution
Here is the code:
static void Main(string[] args)
{
// Inputs
Console.Write("Enter first number: ");
string input1 = Console.ReadLine();
double number1 = Convert.ToDouble(input1);
Console.Write("Enter second number: ");
string input2 = Console.ReadLine();
double number2 = Convert.ToDouble(input2);
// Calculations
double sum = number1 + number2;
double difference = number1 - number2;
double product = number1 * number2;
double quotient = number1 / number2;
// Output
Console.WriteLine("Sum is " + sum);
Console.WriteLine("Difference is " + difference);
Console.WriteLine("Product is " + product);
Console.WriteLine("Quotient is " + quotient);
// Waiting for Enter
Console.ReadLine();
}
Mathematical Functions
When you do engineering or financial calculations , you often need more complex operations than the four basic ones shown in the previous exercise. Now you will see how to perform the complex operations using built-in (predefined) mathematical functions.
Task
To get you a taste of the mathematical functions available, you will calculate the sine and the square root of the entered numbers in this task (see Figure 9-5).
Figure 9-5 Calculating the sine and the square root
Solution
Here is the code:
static void Main(string[] args)
{
// Input of angle
Console.Write("Enter an angle in degrees: ");
string input = Console.ReadLine();
double angleInDegrees = Convert.ToDouble(input);
// Calculation and output of sine value
double angleInRadians = angleInDegrees * Math.PI / 180;
double result = Math.Sin(angleInRadians);
Console.WriteLine("Sine of the angle is: " + result);
// Input of a positive number
Console.WriteLine();
Console.Write("Enter a positive number: ");
input = Console.ReadLine();
double number = Convert.ToDouble(input);
// Calculation and output of square root
Console.WriteLine("Square root of the number is: " + Math.Sqrt(number));
// Waiting for Enter
Console.ReadLine();
}
Discussion
Note the following:
To calculate values of mathematical functions , you use the Math object; it contains many useful functions, not just the ones shown.
The Sin function requires the angle to be specified in radians. If your input is in degrees, which is usually the case, you need to make a conversion.
With the second input (a number), you “recycled” the variable input that was already used before; you used it a second time since you did not need the stored value anymore. However, this means you do not declare the variable a second time.
You do not have to “recycle” variables; variables are not precious resources these days. But you can if you want, which is what I showed you.
Contrary to the first calculation, you did not store the calculated square root into any variable. You directly wrote the calculation into the output statement (WriteLine).
If the user enters a negative number, its square root cannot be calculated , and the result becomes NaN (which means “not-a-number”).
Integer Division
When programming, surprisingly often you will need to work with integer division, which is division with a remainder. For example, 33 divided by 7 is either 4.71428… normally or 4 with remainder 5.
On various computing platforms, you will do integer division differently from “normal” division. Unfortunately, in C#, you use the same operator, the slash (/), for both types. It works like this:
If you put a slash between two values of the int type, the slash performs integer division.
If at least one of the two values is of double type, the slash performs “normal” division.
This behavior may be the source of ugly, difficult-to-find errors. The behavior is 45 years old and stems from when the C language was created; unfortunately, several newer languages, such as C#, inherited the behavior. Just be aware of it and be careful when using a slash.
Task
In this exercise, you will explore “normal” and integer divisions of the two numbers entered by the user (see Figure 9-6).
Figure 9-6 Exploring “normal” and integer divisions
Solution
Here is the code:
static void Main(string[] args)
{
// Inputs
Console.Write("Enter 1. whole number (dividend): ");
string input1 = Console.ReadLine();
int number1 = Convert.ToInt32(input1);
Console.Write("Enter 2. whole number (divisor): ");
string input2 = Console.ReadLine();
int number2 = Convert.ToInt32(input2);
// Integer calculations
int integerQuotient = number1 / number2;
int remainder = number1 % number2;
// "Normal" calculations
double number1double = number1;
double number2double = number2;
double normalQuotient = number1double / number2double;
// Alternatively
double normalQuotientAlternatively = (double)number1 / (double)number2;
// Outputs
Console.WriteLine("-----------------");
Console.WriteLine("Integer quotient: " + integerQuotient +
" with remainder " + remainder);
Console.WriteLine(""Normal" quotient : " + normalQuotient);
Console.WriteLine(""Normal" quotient (alternatively): " + normalQuotientAlternatively);
// Waiting for Enter
Console.ReadLine();
}
Discussion
Note the following:
To compute the remainder , you use the % operator (percent sign).
I have shown you two ways to force the entered values to doubles to achieve “normal” division.
Assignment to variables of type double.
Type cast to double; you prepend the value with the target type in parentheses.
Summary
In this chapter, you explored numbers in a greater detail. You already knew about the difference between integers and decimal numbers in computing, and you knew how to read integers; in this chapter, you learned how to read decimals. You also found out that reading decimal numbers is language sensitive and can lead to surprising results when not being careful. If you do not specify the language to be used, the numbers are read using the Windows language settings. Specifically, you studied the following:
Using the Convert.ToDouble method to convert textual user input into an actual decimal numbers
Storing the converted value in a variable of type double
Enforcing language settings with the CultureInfo object passed as a second parameter to the conversion method
In addition, you learned how to do basic arithmetic using the operators +, -, *, and /, and how to do more complex operations using built-in mathematical functions of the (static) Math object.
Finally, you explored integer division and its comparison to “normal” division and got to know about some tricky behavior of the slash operator, which performs the following:
Integer division when used with two integers
“Normal” division when at least one of the numbers is a decimal
You learned how to force “normal” division even with integers:
Either assigning them to double-typed variables prior to calculation
Typecasting them within the calculation