tags:

views:

530

answers:

7

Is there a library function in c# for the mathematical modulus of a number - by this I specifically mean that a negative integer modulo a positive integer should yield a positive result.

edited to provide an example:

-5 modulo 3 should return 1

A: 

Might be the % operator?

http://msdn.microsoft.com/en-us/library/0w4e0fzs.aspx

AndrewVos
No this doesn't yield a positive result when doing -5 % 2
Snake
He wants `-5 % 2` to be **+1**, not -1.
SLaks
+8  A: 

Try (a % b) * Math.Sign(a)

Try this; it works correctly.

static int MathMod(int a, int b) {
    return (Math.Abs(a * b) + a) % b;
}
SLaks
This gives -5%4 = 1, but it should be 3.
Craig Stuntz
@Craig: Fixed..
SLaks
+1 for being the first to post a correct algorithm (but watch out for overflow!). To strictly answer his question, though, no, there's nothing built into the framework for this.
Craig Stuntz
much better than the no-brains-required while (a < 0) {a += b;}
penguat
Accepted as the first correct algorithm, but I think I am more likely to use ((a % b) + b) % b
penguat
+3  A: 

You might write your own like Math.Abs(x % y);

Paolo Tedesco
Same issue as SLaks's answer; this is indeed positive, but not really a modulus.
Craig Stuntz
This is not correct - try running it with the example provided.
penguat
Sorry, I had misunderstood the question. Your ((a % b) + b) % b seems the best solution.
Paolo Tedesco
+4  A: 
x < 0 ? ((x % m) + m) % m : x % m;
Michael Petito
Why use the ternary operator?
penguat
@penguat: Because if x is non-negative then there is no reason to go through the extra work.
Michael Petito
I'm not sure which is more work on average, the conditional or the fixed addition and modulus, not that it matters in my case. This answer is correct, anyway. Thanks.
penguat
@penguat: Hard to say; I always consider division and modulus operations to be relatively expensive (unless they are trivial, as in divide by 2 or mod 2). I imagine the overhead of the ternary operator is only a few cycles for the check and jumps. Plus, there is no chance for overflow with non-negative x in this computation. However, without the ternary operator, you could overflow if `x = 1` and `m = int.MaxValue` (or in any scenario where 0 < x < m and x + m > int.MaxValue).
Michael Petito
I would definitely guess that the extra modulo is faster than the branch on modern processors. However, I've never tested it, so I don't really know. Also, it's a pretty slight distinction.I'm not sure which is more readable. I was going to say without the ternary operator at first, but when I think about it that x < 0 does tell the reader why we're doing something fancy without having the need for a comment.
clahey
+3  A: 

Well the definition (if I'm not mistaken) is something like this

a mod b = a - b * floor(a/b)

It's probably pretty slow and beware of integer division just like built in modulus :)

Other option is to modify the result of built-in modulus according to the signs of operands. Something like this:

if(a < 0 && b > 0)
{
    return (a % b + b) % b;
}
else if ....
Maciej Hehl
This answer is also correct, thanks.
penguat
A: 

Fix :

(ans=a%b)<0 ? (a<0 && b<0 ? (ans-b)%(-b) : (ans+b)%b) : ans

Mister_Egg_Head
what about -10 mod 3? your solution would give -1 where the required answer is 2.
penguat
@penguat a=-10 , b=3 ans= -1 < 0 , so solution = (-1+3) % 3 =2 what's wrong ?
Mister_Egg_Head
Ah, sorry, I misread it.
penguat
A: 

If you're using any of these algorithms and you need to do division also, don't forget to make sure that you subtract 1 when appropriate.

I.e.,

if -5 % 2 = -1 and -5 / 2 = -2, and if you care that -5 / 2 * 2 + -5 % 2 = -5, then when you calculate -5 % 2 = 1, that you also calculate -5 / 2 = -3.

clahey
I'm not quite sure what you're getting at here... I'd normally preserve the original number rather than try to reconstruct it.
penguat
I'm not suggesting you reconstruct it. I was just concerned that your algorithm might use the / operator as well and depend on them being consistent.
clahey