Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C weird modulo operation

Tags:

c

modulus

So I've got this thing where I got the following operation:

NSInteger articleIndex = self.featuredArticlesCounter % self.featuredArticles.count;

In this case self.featuredArticlesCounter is -1 and
self.featuredArticles.count is 10

So it's basically -1 % 10, which should be 9, but the result is 5 instead.

Google says it's 9.

And if I do NSInteger articleIndex = -1 % 10; it gives me -1

I've tried casting the NSUInteger from count to NSInteger and that doesn't work. I've tried inserting brackets all over the place but that didn't work either.

I've since switched to using ((-1 % 10) + 10) % 10.

But I'm still wondering what the deal is here. Any ideas?

Edit:

featuredArticlesCounter is a signed int

self.featuredArticles.count is an unsigned int

like image 281
Andrew Avatar asked Jan 13 '23 12:01

Andrew


2 Answers

featuredArticlesCounter is evidently an unsigned int. When you thought you set it to -1, you really set it to 2**32 - 1 (~0). That number mod 10 is 5. (Apparently, 2**(8k)-1 % 10 is 5, so it doesn't matter what size unsigned it actually is)

As for why -1 % 10 is -1, I believe in C the mod of negative numbers is implementation-defined, but in this case (as in Java), it is defined such that x / y + x % y == x. If you plug negative numbers in, -1 / 10 + -1 % 10 = -1 -> -1 % 10 = -1.

like image 156
Kevin Avatar answered Jan 19 '23 01:01

Kevin


Perhaps the hardware (or software?) treats the number as an unsigned integer:

  1. -1 == 0xFFFFFFFF (in two's compliment encoding)

  2. 0xFFFFFFFF == 4294967295 (assuming the raw data is an unsigned integer)

  3. 4294967295 % 10 == 5 (trivial by observation of last digit)

This would be my best guess.

like image 22
recursion.ninja Avatar answered Jan 19 '23 00:01

recursion.ninja