You are here:

- Home
- Computing/Technology
- C/C++
- C++
- Rate question - Hz

Advertisement

I have a line of code that says

if(g100Hzframectr%100==0){...

which is defined in the comment as processing at 1 hz and another if(g100Hzframectr%10==0){... defined as 10 hz. This makes sense, but a third line says if(g100Hzframectr%50==2){...

I think I am misunderstanding the % and how it is being used, and ==0 vs. ==2.

Can you help?

Yes and no.

I cannot state what the intention of the code is as I do not have enough information, particularly I have no real idea what the value of g100Hzframectr represents other than it is prefixed by a g, which is sometimes used to indicate a global variable (in which case I may query whether this is a good idea as good design tries to minimise the use of global) and the name suggests it relates in some way to a 100Hz frequency and some frame something (ctr - centre, control, ... ??).

However I can explain what the % operator in C and C++ does and therefore which values of g100Hzframectr will give true values to the if statements' Boolean expressions.

The C and C++ % operator is the modulus operator. It is useful only for integer values. The modulus is the remainder of one value divided by another: 10 modulus 3 gives 1; that is 10 / 3 is 3 remainder 1. In C or C++ we would then write 10 % 3 and get a result of 1.

One point about modulus operations is that their results are cyclic for increasing values of the left hand side for the same right hand side value:

0 % 3 == 0

1 % 3 == 1

2 % 3 == 2

3 % 3 == 0

4 % 3 == 1

5 % 3 == 2

6 % 3 == 0

7 % 3 == 1

8 % 3 == 2

.

.

.

Notice that the result is zero for a right hand side value of zero or any value that is a multiple of the right hand side (OK so strictly zero is a multiple of any value I suppose, but I shall keep it separate as it is often a forgotten case). This is to be expected: If one value is a multiple of another dividing it by that value will by definition have a zero remainder: a * b = c => c / b = a with 0 remainder.

Notice also that the nonzero remainder values can be considered as offset from 0 and multiples of the right hand side value. Thus in the above examples a result of 2 occurs for 0 + 2 and (multiple of 3) + 2: 0+2, 3+2, 6+2, ...

Note that modulus only applies to integer arithmetic because when we divide using integer arithmetic (as we were taught in school) we specify the result in two, whole number (i.e. integer) parts:

- the value of the number of times one value goes into another

- the value of the remainder

This is not the case for real numbers, in which dividing one real number by another yields a single real number result.

OK so that is how the %, modulus or remainder, operator works. So how does it apply to the three if statements you showed?

First you have an if with the condition:

g100Hzframectr%100==0

This means that the condition will be true for values of g100Hzframectr that are 0 and multiples of 100:

0, 100, 200, ..., 1000, 1100, ..., 2000, 2100, ..., 10000, ...

Next you have an if with the condition:

g100Hzframectr%10==0

This means that the condition will be true for values of g100Hzframectr that are 0 and multiples of 10:

0, 10, 20, ..., 100, 110, ..., 200, 210, ..., 1000, 1010, ...

And finally, the one that has you confused, you have an if with the condition:

g100Hzframectr%50==2

This means that the condition will be true for values of g100Hzframectr that are 2 and (multiples of 50) + 2:

2, 52, 102, 152, 202, ..., 1002, 1052, 1102, ..., 2002, ...

So I would guess that maybe your understanding of % is OK and the person who wrote the code was confused as the final results look a bit strange.

I would try to find out what the code should be doing then see if it actually is doing that.

Here is a quick and dirty C++ program to check the values each if statement would match (i.e. all values for which the if condition is true for):

#include <iostream>

#include <iomanip>

#include <vector>

#include <algorithm>

// Type alias for values of g100Hzframectr & related objects

typedef unsigned int ValueType;

// Type alias for collections of matched ValueType values

typedef std::vector<unsigned int> MatchedValuesType;

// Functor class used with the std::for_each algorithm

// to display a single value from a collection of values.

//

// Instances are stateful, but copyable.

//

// Each instance keeps track of the width of the value display

// field and the number of fields that can fit on one line.

//

// Instances are constructed from a field width value and

// a display line length value (both in characters).

//

// The fields per line value is calculated from these values.

class PrintValue

{

unsigned int iCount; // Count of values on current line

unsigned int iFieldWidth; // Width of value display field

unsigned int iFieldsPerLine; // Value display fields per line

public:

// Construct from field width and line length.

// Values default to a width of 5 characters and

// a line length of 72 characters.

PrintValue(unsigned int fieldWidth=5, unsigned int lineLength=72)

: iCount(0)

, iFieldWidth(fieldWidth)

, iFieldsPerLine( lineLength / fieldWidth )

{}

// Function call operator.

// Takes value to be displayed and inserts it into the

// std::cout stream specifying a field width of iFieldWidth.

// Increments the count of values displayed on current line.

// If this count equals iFieldsPerLine then resets count to

// zero and starts a new line.

void operator()(ValueType v)

{

std::cout << std::setw(iFieldWidth) << v;

++iCount;

if ( iCount == iFieldsPerLine )

{

iCount = 0;

std::cout << '\n';

}

}

};

// Main program entry point.

int main()

{

// Collections for storing matched values for each if condition

MatchedValuesType matched_mod_100_eq_0;

MatchedValuesType matched_mod_10_eq_0;

MatchedValuesType matched_mod_50_eq_2;

// Maximum value we will consider for g100Hzframectr

ValueType const MaxValue(1000);

// Loop setting g100Hzframectr from zero to MaxValue

for ( ValueType g100Hzframectr=0

; g100Hzframectr<=MaxValue

; ++g100Hzframectr

)

{

// Test each value against each if condition.

// For each true case add value to collection of

// matched values for specific if condition:

if ( g100Hzframectr % 100 == 0)

{

matched_mod_100_eq_0.push_back( g100Hzframectr );

}

if ( g100Hzframectr % 10 == 0)

{

matched_mod_10_eq_0.push_back( g100Hzframectr );

}

if ( g100Hzframectr % 50 == 2)

{

matched_mod_50_eq_2.push_back( g100Hzframectr );

}

}

// Write out matching values for each

// if condition collected above:

//

// If you wish to use fieldWidth or lineLength

// other than the defaults then use one of the

// following forms as the 3rd parameter to

// std::for_each:

//

// PrintValue( requriedFieldWidth )

//

// for a specific field width with default line length or

//

// PrintValue( requriedFieldWidth, requiredLineLength )

//

// to specify both fieldWidth and lineLength

//

std::cout << "g100Hzframectr % 100 == 0 matched values:\n";

std::for_each ( matched_mod_100_eq_0.begin()

, matched_mod_100_eq_0.end()

, PrintValue()

);

std::cout << "\n\ng100Hzframectr % 10 == 0 matched values:\n";

std::for_each ( matched_mod_10_eq_0.begin()

, matched_mod_10_eq_0.end()

, PrintValue()

);

std::cout << "\n\ng100Hzframectr % 50 == 2 matched values:\n";

std::for_each ( matched_mod_50_eq_2.begin()

, matched_mod_50_eq_2.end()

, PrintValue()

);

std::cout << std::endl;

}

The program assumes a fairly ISO standard C++ implementation. In particular it assumes access to an reasonably ISO standard C++ library, making use of standard collections and algorithms. I compiled the code and ran it using Microsoft Visual C++ 2005 (Win32 debug build) on Microsoft Windows Vista Business x64 edition and under g++ 4.1.3 on x64 Ubuntu Linux Desktop version 7.10.

The idea is to iterate through values of g100Hzframectr from 0 to some maximum value (currently set to 1000). For each value the if statements you showed in your question are used. Each time the condition is true and the if clause is executed the value of g100Hzframectr is added to a collection of matching values for that if statement condition. After iterating through g100Hzframectr values and collecting matching values completes the matched values for each of the three conditions are displayed one after the other. The output should look like so:

g100Hzframectr % 100 == 0 matched values:

0 100 200 300 400 500 600 700 800 900 1000

g100Hzframectr % 10 == 0 matched values:

0 10 20 30 40 50 60 70 80 90 100 110 120 130

140 150 160 170 180 190 200 210 220 230 240 250 260 270

280 290 300 310 320 330 340 350 360 370 380 390 400 410

420 430 440 450 460 470 480 490 500 510 520 530 540 550

560 570 580 590 600 610 620 630 640 650 660 670 680 690

700 710 720 730 740 750 760 770 780 790 800 810 820 830

840 850 860 870 880 890 900 910 920 930 940 950 960 970

980 990 1000

g100Hzframectr % 50 == 2 matched values:

2 52 102 152 202 252 302 352 402 452 502 552 602 652

702 752 802 852 902 952

Hope this helps.

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines.
Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is).
When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD.
My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes.
I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.**Education/Credentials**