You are here:

C++/Rate question - Hz

Advertisement


Question
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?

Answer
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.  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

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.

Experience

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

©2016 About.com. All rights reserved.