Basic Calculations
Increment Operator
Decrement Operator
Randomization
This brief chapter discusses simple but essential C# math operators and methods. Coverage of numeric operators and math methods may seem trivial, but understanding these topics is essential for implementing programming logic. While we are on the topic of operations with numbers, this chapter also provides a modest introduction to randomizing numbers.
Let’s first examine operators and methods that allow you to write routines that you would find in most basic calculators.
Addition uses the + operator. As you would expect, addition is performed by placing both operands at opposite sides of the + operator. Also, the compound operator, +=, reassigns a variable on the left with its starting value plus the right operand value.
Subtraction requires the – operator. Obviously, in an equation you can subtract an operand on the right of the – operator from the operand on the left. The minus assignment operator combination, –=, reassigns a variable with its starting value minus the right operand.
The multiplication operator is represented with *. You can calculate a product of two numbers by placing each number at opposite sides of the * operator. The multiplication assignment operator, *=, reassigns a variable on the left with its original value multiplied by the right operand.
The division operator is /. Division is performed by placing the numerator on the left of / and the denominator on the right. The /= combination reassigns a variable at the left with its starting value divided by the right operand.
The modulus operator, %, is used to calculate the remainder during division. It is also possible to implement a self-assignment using a compound combination of %=.
The System namespace of the .NET Framework provides a Math class that offers methods for more advanced calculations. To automate exponentiation, the Math class offers a Pow() method that receives the base value and exponent as parameters. The Pow() method returns the result as a double type. This example shows how Pow() raises 3 to the power of 2:
double result = Math.Pow(3, 2); // 32 = 9
The Math class provides the Sqrt() method to calculate square roots:
The increment operator, ++, adds 1 to a numeric type variable. Placement of this operator before or after a variable determines when the variable value is updated. Understanding how this operator works is essential to becoming a skilled programmer because it is a fundamental feature of most mainstream programming languages. The increment operator’s importance will be apparent when we discuss for loops in Chapter 5.
Placing the ++ operator before a numeric variable creates a pre-increment expression. A pre-increment expression immediately adds 1 to the variable value when the instruction is executed:
int number = 5;
Console.WriteLine(++number); // Displays 6
Placing the ++ operator after a numeric variable creates a post-increment expression. A post-increment expression adds 1 to the variable on the line after this instruction is executed:
This exercise offers a chance to observe the difference between the operators +, +=, and ++ (in both pre-increment and post-increment expressions).
1. In a brand new console application, declare an integer variable and initialize it with the value of 7.
2. Using a combination of +, +=, and ++ pre-increment and post-increment operators, write four instructions that increment the variable value by 1. Each instruction must increment the variable in a manner that is unique when compared to all other instructions in the program.
3. Design your program so the output generated looks like the following:
Original value: 7
Incremented value: 8
Incremented value: 9
Value during post-increment execution: 9
Incremented value: 10
Incremented value: 11
The decrement operator, --, reduces a variable value by 1. Similar to the increment operator, placement of the decrement operator before or after the variable determines when the variable is actually decremented.
When the decrement operator is placed before a numeric variable, the value is reduced by 1 immediately:
int number = 5;
Console.WriteLine(--number); // Displays 4
When the decrement operator is placed after a numeric variable, the value is decremented on the line after the post-decrement instruction:
int number = 5;
Console.WriteLine(number--); // Displays 5
Console.WriteLine(number); // Displays 4
TIP
When reassigning variable values while adding, subtracting, multiplying, or dividing, always use compound assignment, pre-/post-increment expressions, or pre-/post-decrement expressions. It easier to write +=, –=, *=, /=, ++, or -- compared to writing the longhand form. Expressions using compound shorthand assignments are more efficient because the variable being reassigned needs to be evaluated only once. Any experienced programmer who reads your code and sees a long expression like x = x + 1 may interpret this as a sign of inexperience.
You may at times need to generate random numbers. Random number generation is useful and necessary for implementing security routines, randomizing video game play, and creating unique identifiers for objects in your application. One of the easiest ways to perform randomization is with the Random class from the System namespace.
The default Random constructor generates a number that is based on the system clock. A random variable is created with a new instance of the Random class.
CAUTION
Since the random variable is instantiated with the system clock, creating multiple Random objects in quick succession can generate repeating random number sequences that are not random. It is acceptable, however, to use the default Random constructor to generate Random objects if one Random object instance is used to create many random numbers over time.
Three methods exist in the Random class to generate random integers. The Next() method with no parameters generates an integer that is greater than or equal to 0 and less than 2,147,483,647:
The Next() method with an integer parameter generates an integer between 0 and the exclusive upper bound that is specified by the parameter. Since the upper bound is exclusive, in the following case, numbers generated may include 0 to 999999998:
The Next() method with two parameters generates an integer between an inclusive minimum and an exclusive upper bound. For the following case, numbers that might be generated with a minimum of 100,000,000 and an upper bound of 999,999,999 could include any number from 100,000,000 to 999,999,998:
The NextDouble() method of the Random class generates a double-precision floating point number greater than or equal to 0.0 and less than 1.0:
Example 3-1 Default Random Generation
This example shows how a default Random object may be declared to generate many random values. Each time that you run the program, a random number is generated with a different method to restrict the number type and range:
The output from running this program will be similar to the following text:
Example 3-2 Improper Random Number Generation
As mentioned earlier, creating multiple instances of a Random object to generate random numbers in quick succession leads to repeating number sequences. Here is a poorly written program that fails to create truly random numbers:
When you run the program, you may see some unique numbers, but you will likely see repeated numbers:
1056405274
1056405274
1056405274
Another technique that is used for avoiding repeating number sequences when generating random numbers involves passing a random integer value, called a seed, to the Random class constructor. The seed is used to calculate the starting point for the number sequence:
static Random random = new Random(int seedValue);
When the seed is always the same, the sequence is always repeated. If the seed is random, then the sequence will be unpredictable.
This exercise shows how improperly seeded Random objects will not generate random numbers.
1. Write a program that creates two Random objects with a seed value of 5.
2. Generate random numbers with each object using the NextDouble() method.
3. Notice that both numbers that are generated are identical.
How can you create a random seed when you are trying to create a random number? Microsoft suggests generating a random array of bytes with the help of the RNGCryptoServiceProvider class from the System.Security.Cryptography namespace. The byte array can then be converted to a random string, which in turn can be converted to an integer, which may then be used as the seed.
To generate a random array of bytes, you first need to create a byte array:
Then, after referencing the System.Security.Cryptography namespace, an instance of the RNGCryptoServiceProvider class is required:
// Generate Cryptography class object.
RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();
Now the GetBytes() method of the RNGCryptoServiceProvider class can generate and store the random byte array:
crypto.GetBytes(byteArray);
The ToInt32() method of the BitConverter class from the System namespace can convert the random byte array to the integer seed value. The first parameter of the ToInt32() method receives the byte array, and the second parameter is the starting index of the byte array:
int seed = BitConverter.ToInt32(byteArray, 0);
Example 3-3 Generating a Random Number with a Random Seed
This example shows all of the steps needed to create a random seed, which can then be used to generate a Random object:
The output shows the random seed value and the random integer between 1 and 99:
Seed value: 643640352
Random integer between 1 and 99: 84
The following questions are intended to help reinforce your comprehension of the concepts covered in this chapter. The answers can be found in the accompanying online Appendix B, “Answers to the Self Tests.”
1. In the equation Vfinal = Vinitial + a * t
V = velocity (meters per second)
a = acceleration (meters per second squared)
t = time taken (seconds)
Using this equation, write a program to calculate the velocity of an object after 20 seconds when Vinital = 10 m/s and acceleration has remained constant at 0.5 m/s2.
2. Examine this code:
Without the help of a computer, determine the number that is written to the window.
3. Examine this code:
Without the help of a computer, determine the number that is written to the window.
4. What two techniques are recommended for generating random numbers when multiple random numbers are required?
5. Create a new program that generates two random numbers with Random objects that are created using random seeds that are generated with the RNGCryptoServiceProvider class. Each number must be greater than or equal to 1 and less than or equal to 21. Display the results.