Modulus Operator Usage

Started by
15 comments, last by lightxbulb 10 years, 12 months ago

ike Khatharr said, in C/C++ it would actually execute every time except when count is 0.

As a quick test:


for(index = 0; index < 10; ++index)
{
     count = ++count % 7;
     if(count)
     {
          std::cout << count << " ";
     }

}

produced output:


1 2 3 4 5 6 1 2 3

Yup, I goofed.. smile.png Please don't hang me at the weekly horribly backwards post meeting GameDev holds every week. smile.png

Advertisement


talking

Blah, sorry.... Typo, "non-zero".. smile.png


No worries. It's a good point you brought up.
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

Also, addressing the general topic, if you're wanting both the quotient and the remainder then check to see if there's an intrinsic that can give you both results without having to do the division twice. When the CPU does integer division it actually produces both results, regardless of whether you asked for division or modulus. It's not a huge issue, but division is the heaviest integer math operation for the cpu by a wide margin, so in anything where performance matters it can be good to know if there's an intrinsic. (Don't prematurely optimize, but don't prematurely pessimize either.)

Edit: Apparently there's one in std::div, which is convenient, but poking around for a minute I see that it's common for modern compilers to optimize this problem away in most cases.

I was sort of going to "ask" about that. I knew that division was the "heaviest" integer math for the most part. So I was going to ask if the CPU did something to store both results. though I didn't want to seem like I was trying to "optimize" something or anything like that. I was going to ask out of curiosity. Though felt like it could go beyond this topic and didn't want to get into premature optimization. lol. Just my nerd curiosity. :) Thanks.

Some practical everyday uses:

// I want to trigger something every 7 executions:

static int count = 0;

count = ++count % 7;

if( count ) {do something}

// I want to cycle 0-6 repeatedly.

static int count = 0;

count = ++count % 7;

In the first case the 'if' relies on the fact that the only "true" condition is when something is zero. In the second case a value modded by any higher value results in the same value, it goes to zero when modded with itself. Basically a variable in both cases is going to step from 0 to mod value minus one, or 0-6 in this case and keep repeating.

I think I use the first case with the 'if' statement more often but I know I use the second case on occasion also.

Like Khatharr said, in C/C++ it would actually execute every time except when count is 0.

As a quick test:


for(index = 0; index < 10; ++index)
{
     count = ++count % 7;
     if(count)
     {
          std::cout << count << " ";
     }

}

produced output:


1 2 3 4 5 6 1 2 3

Yup, I goofed.. smile.png Please don't hang me at the weekly horribly backwards post meeting GameDev holds every week. smile.png

I won't...to much. :).

I saw your new post after I posted mine, so I edited. Gamedev didn't notify me of a new post with the code editor up. Or i didn't see it. lol. :)

EDIT: Nvm, no reason for this post I guess. lol. Typo. smile.png

Like Khatharr said, in C/C++ it would actually execute every time except when count is 0.

Actually, this is a good case of a bad code typo and use case. The fact that I got the example wrong led me to describe the wrong case and I didn't even notice it and I'm a pretty annoying person about details like that..... It leads me to suggest any use of modulus should probably be documented with a comment as to the expectations.. :)

You can use mod for "wrapping values":


#include <iostream>
#include <string>
using namespace std;

enum DaysOfWeek
{
	Sunday = 0,
	Monday,
	Tuesday,
	Wednesday,
	Thursday,
	Friday,
	Saturday
};

int main()
{

	int input;
	cout << "Enter a number for the day of the week you want: ";
	cin >> input;
	if(input>6)
		input = input % 7;
	if(input<0)
		input = (input % 7) + 7;

	string result;

	switch(input)
	{
	case Sunday:
		result = "Sunday";
		break;
	case Monday:
		result = "Monday";
		break;
	case Tuesday:
		result = "Tuesday";
		break;
	case Wednesday:
		result = "Wednesday";
		break;
	case Thursday:
		result = "Thursday";
		break;
	case Friday:
		result = "Friday";
		break;
	case Saturday:
		result = "Saturday";
		break;
	}

	cout << result << endl;

	cin.sync();
	cin.ignore();

	return 0;
}

Careful now...


    if(input>6) //this condition is (usually) not an effective optimization and is mathematically irrelevant
        input = input % 7;
    if(input<0)
        input = (input % 7) + 7; //this is incorrect in cases where input == n * -7

Try:


    input %= 7;
    if(input<0)
        input +=  7;
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

Careful now...


    if(input>6) //this condition is (usually) not an effective optimization and is mathematically irrelevant
        input = input % 7;
    if(input<0)
        input = (input % 7) + 7; //this is incorrect in cases where input == n * -7

Try:


    input %= 7;
    if(input<0)
        input +=  7;

Thanks about this! Seems I didn't predict the case when (-7*n) % 7 = 0 tongue.png

(In fact I think I did predict it but messed up my conditionals...sad.png gotta be careful when coding)

This topic is closed to new replies.

Advertisement