27

Basically, I need (-3) % 5 to be "2" instead of "-3". Python produces "2", but C++ produces "-3". Not sure how to produce "2" in C++. Thanks!

1
  • Keith raises an important point in a comment. Is your second operand always positive? If not, what should happen when it's negative? Commented Dec 10, 2012 at 3:11

6 Answers 6

34

Most easily: ((x % 5) + 5) % 5

Sign up to request clarification or add additional context in comments.

1 Comment

This solution is very suboptimal. It performs two separate divisions, which may be very expensive. It also isn't safe against overflow for huge divisors, assuming that you don't just use 5 but something else.
9

Add the base if the input number X is negative:

X % Y + (X % Y < 0 ? Y : 0);

2 Comments

And confirm whether you need to handle Y<0 as well.
X == -5; Y == 5; X % Y == 0; (X < 0 ? Y : 0) == 5;
7

The quick & dirty way is to write

((x % divisor) + divisor) % divisor

For example, ((-3 % 5) + 5) % 5 == 2. However this performs two separate divisions, and since divisions are one of the slowest arithmetic operations you might like one of these alternatives:

(1) General mod for integer or floating point

int mod(int x, int divisor)
{
    int m = x % divisor;
    return m + (m < 0 ? divisor : 0);
}

template<class Num> Num mod(Num x, Num divisor)
{
    Num m = x % divisor;
    return m + (m < 0 ? divisor : 0);
}

(2) Non-branching mod for 32-bit integers

int mod(int x, int divisor)
{
    int m = x % divisor;
    return m + ((m >> 31) & divisor);
}

All this assumes that the divisor is always positive.

1 Comment

The generalised version won't work. % operator isn't for floats. replacing it with std::modulus(x, divisor) might?
4

You can add some multiple of 5 to the negative number first, to convert it to a positive number with the same value mod 5.

You can do that by taking the absolute of the negative number, adding whatever is needed to round it up to the next multiple of 5, and then add it to your negative number, and that should already be a number between 0 and 4.

Alternatively, simply do something like:

num = -2;
mod = 5;
if ( num < 0 ) {
    result = mod - (abs(num) % mod);
}

and it'll work (explanation: mathemagic)

4 Comments

@djechlin: I don't think you followed what sampson-chen was suggesting, something like: (x + (abs(x)+y-abs(x)%y)) % y
@djechlin the point of the absolute part is just so you start with some number bigger in magnitude than the negative number, and then you move up to the closest multiple of 5. That actually does preserve the value mod 5. Sorry if my wording was confusing in the original answer =p
This should be the correct answer, since it's the only one that works if it's off by more than 1 multiple of mod. As Hailiang Zhang said, the code would fail if num%mod==0; I fixed it in an edit just now.
@AlexMeiburg no idea what you are talking about. Maybe comment on my answer if you feel it is incorrect, with an example?
0
int x=-3;

// first approach
cout<<((x % 5) + 5) % 5;

//second approach means just reverse the number modNum%x
cout<<5%x;

Comments

-2

I see a lot of suggestions for ((x % 5) + 5) % 5 But I'm getting the same result with just (X + 5) % 5

(X + divisor) % divisor.

2 Comments

This will not work if X + divisor < 0, for example, for -13 % 5.
@zkoza you're right, it only works for me because I'm never adding or subtracting numbers smaller than my divisor. Good point.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.