The Modulus Operator ()

   


The Modulus Operator (%)

The modulus operator, represented by the percent symbol ((%), is the last unmentioned binary operator of Table 7.1. The modulus operator has the same precedence as the division and multiplication operators. It can only be used with integer numbers and returns the remainder of dividing the first (left) operand with the second (right) operand. For example 20 % 7 is 6 because 7 goes into 20 two times, 2 * 7 = 14 and 20 - 14 = 6, which is the remainder. An often-used algebraic notation to denote a modulus calculation is the abbreviation mod. Thus, 20 % 7 in mathematics is often written 20 mod 7. Table 7.2 gives an overview of the five binary operators and how typical arithmetic expression are written in C#.

Table 7.2. The Binary Operators: Arithmetic and C#
Operation Symbol Arithmetic Expression C# Expression
Addition + cost + 100 cost + 100
Subtraction - 20 sum 20 - sum
Multiplication *

pricextax or

price tax

price * tax
Division /

p/q or

p÷q or

P

graphics/q.gif
p/q
Modulus % x mod y x % y

The modulus operator is useful for solving many more programmatic problems than its simple appearance seems to indicate. For example, consider a program containing an algorithm that, among other things, is counting numbers (1, 2, 3, 4, 5, 6, 7, and so on) with a variable called count. You want to detect every number counted that is divisible by two. To solve this programmatic problem, you merely need to ask if (count % 2) is equal to zero, because the numbers 2, 4, 6, and so on have a remainder of 0 when divided by two. This method also applies when finding numbers divisible by 3, 4, 5, and so on.

Another useful application is conversions from one unit to another, such as converting inches to feet and inches or dollars to quarters, dimes, nickels, and pennies.

The following case study shows the modulus operator in action. It is used to find every 7th number in a list of numbers { 1, 2, 3, 4, 5, 6, 7, and so on} representing days in a day-counting algorithm.

Case Study:Day Counter Algorithm for Elevator Simulation

Software Specification

The algorithm described here could be part of the internal timekeeper system of an elevator simulation program. It simulates "days" passing by and, consequently, determines which day it is inside the simulation and perhaps whether it is a busy day or a holiday. It also enables the user of the simulation program to determine the total amount of "days" the "elevator system" will run during one particular simulation.

Our algorithm must count the "days" for which the simulated elevator system has been running. Additionally, it is required to report how many "weeks" and "days" for which the simulation has lasted. For example, if the system has run for 23 days, we want the algorithm to report 3 weeks and 2 days.

Finally, the algorithm must provide a signal to the elevator control system whenever the current "day" is a "Sunday." The latter is important because the system goes into a "low-traffic" mode on "Sundays" for efficiency purposes.

Software Design:

We will jump straight to the algorithm design stage of the software design process, because the specification only involves a very small isolated piece of software (the algorithm), rendering the class and method identification stages superfluous.

Algorithm Design of Internal Method:

Which variables should the algorithms contain? The algorithm will certainly have to know the total running time (in days) of the elevator system. We can call this variable maxSimulationDays and, because it is holding a whole positive number of days, we choose it to be of the unsigned integer type uint. The simulation will further have to keep track of the current number of days the elevator system has been running. This will be represented by the dayCounter variable, also of type uint.

We then need a loop. Every time the loop is repeated, the dayCounter will be incremented by one, the weeks and days will be reported, a Sunday check will be made and an alert reported if it turns out to be Sunday.

The loop will stop when the value of dayCounter has reached the value of maxSimulationDays.

How do we then convert the amount held by dayCounter into weeks and days? The number of weeks is a straightforward division, (dayCounter / 7) which, because we are dealing with integers, will return the whole number of times 7 goes into dayCounter. We then need to find the few remaining days, yes, this is where the modulus operator comes into the picture. The calculation (dayCounter % 7) will do the trick. We now just need a way to detect every Sunday. A Sunday is simply set to be every 7th day counted. But how can the algorithm detect every 7th day passing by? Clearly, the days 7, 14, 21, 28, … are all divisible by 7. Consequently, if (dayCounter % 7) is equal to 0, it's Sunday.

Let's look at the resulting algorithm presented with pseudocode in Listing 7.1. It keeps track of the current day, reports of running time in weeks and days, and alerts when the current day is a Sunday.

Listing 7.1 Pseudocode for "Day Counter Algorithm"
01: Set the variable dayCounter to 0 02: Set the maxSimulationDays to total days the elevator system should run for 03: While dayCounter is less than maxSimulationDays repeat the following block 04: { 05:     Increase dayCounter by one 06:     Calculate and report number of weeks in dayCounter report remaining number of  graphics/ccc.gifdays. 07:     If dayCounter is divisible by 7 send message ("It's Sunday") to the elevator  graphics/ccc.gifcontroller and print: "Hey Hey It's Sunday!" 08:     If used as part of larger simulation program then start elevator simulation  graphics/ccc.giflasting one day 09: } 10: Let user know that the simulation has ended 

The algorithm contains a loop (lines 3 9) that repeats lines 5 8 as long as dayCounter is less than the maxSimulationDays.

It's time to construct the C# code based on the pseudocode. I decided to put the algorithm into the Main() method of the program because we are merely testing a freestanding prototype algorithm. Here is an overview of how the lines of the pseudocode correspond to the lines of the C# source code in Listing 7.2, the final source code.

Pseudocode line Equivalent C# source code line
01 16
02 21 23
03 24
04 25
05 26
06 27 30
07 31 33
08 34
09 37
10 38

Listing 7.2 Source code for DayCounter.cs
01: using System; 02: 03: /* 04:  * The DayCounter class contains a prototype for 05:  * a "Day counter" algorithm with potential use 06:  * in an elevator simulation. 07:  * It keeps track of the current day in simulation 08:  * It reports of running time in days and weeks 09:  * and alerts when current day is a Sunday 10:  */ 11: 12: class DayCounter 13: { 14:     public static void Main() 15:     { 16:         uint dayCounter = 0; 17:         uint maxSimulationDays; 18:         uint weeks; 19:         byte remainderDays; 20: 21:         Console.Write("Please enter the number of days " + 22:             "the simulation should run for "); 23:         maxSimulationDays = Convert.ToUInt32(Console.ReadLine()); 24:         while(dayCounter < maxSimulationDays) 25:         { 26:             dayCounter++; 27:             weeks = dayCounter / 7; 28:             remainderDays = (byte)(dayCounter % 7); 29:             Console.WriteLine("Weeks: " + weeks + 30:                 "   Days: " + remainderDays); 31:             if(remainderDays == 0) 32:                  // TODO send "it's Sunday" message to controller 33:                 Console.WriteLine("\t\tHey Hey It's Sunday!"); 34:              // TODO start simulation lasting for one day. 35:              // Let the program pause for 200 milliseconds 36:             System.Threading.Thread.Sleep(200); 37:         } 38:         Console.WriteLine("Simulation ended"); 39:     } 40: } 

In the following output, the user specifies the simulated elevator system to run for 15 days.

 Please enter the number of days the simulation should run for 15<enter> Weeks: 0   Days: 1 Weeks: 0   Days: 2 Weeks: 0   Days: 3 Weeks: 0   Days: 4 Weeks: 0   Days: 5 Weeks: 0   Days: 6 Weeks: 1   Days: 0                 Hey Hey It's Sunday! Weeks: 1   Days: 1 Weeks: 1   Days: 2 Weeks: 1   Days: 3 Weeks: 1   Days: 4 Weeks: 1   Days: 5 Weeks: 1   Days: 6 Weeks: 2   Days: 0                 Hey Hey It's Sunday! Weeks: 2   Days: 1 Simulation ended 

Lines 24 37 contain a while loop. The braces in lines 25 and 37 surround the block of the while loop, which is repeatedly executed as long as the condition (dayCounter < maxSimulationDays) (meaning dayCounter less than maxSimulationDays) is true. When this condition is evaluated to be false in line 24, the program will continue with line 38.

Line 26 increases the value of dayCounter by one.

Line 27 calculates the number of whole weeks in dayCounter. Because all variables involved in this calculation are of type uint, a whole number will be assigned to weeks.

Line 28 calculates the remaining days of a week using the modulus operator (%). RemainderDays is of type byte and the (dayCounter % 7) expression is of type uint, so an explicit cast is required using the (byte) cast operator.

Because remainderDays is equal to (dayCounter % 7) due to line 28, we need to ask whether remainderDays is equal to zero to find out whether today is Sunday. This is done with an if statement in line 31.

Programmers often use TODO as a reminder for them of things that still remain to be done in a program. TODO marked comments in the program can easily be tracked down by the find command of the source code editor. Line 32 is simply stating that in case this program was part of a real simulation source program, this is where the It's Sunday message would be sent to the elevator controller system of the program.

Note that you could use any arbitrary sequence of letters instead of TODO, such as REMINDME. However, TODO is now so ingrained in the programming community that a sophisticated IDE, such as Visual Studio .NET, recognizes TODO comments and also automatically inserts them at relevant places.

Line 33 uses the TAB (\t) escape character twice to indent the text "Hey Hey It's Sunday!" which is printed out accordingly.

For now, just think of line 36 as a peculiar way of saying pause the program here for 200 milliseconds. The pause will cause the program to write its output in a slower and, in my opinion, more pleasant manner. Feel free to adjust the number 200 if you want to speed up (by decreasing the number) or slow down the program (by increasing the number).

Note

graphics/common.gif

The previous implementation (like most algorithms) could have been designed in several different ways that rely less on the modulus operator. However, the algorithm presented certainly constitutes a valid efficient algorithm.



   


C# Primer Plus
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2000
Pages: 286
Authors: Stephen Prata

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