C语言中奇怪的取模运算

4

我有一个操作,其内容如下:

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

在这种情况下,self.featuredArticlesCounter是-1,
self.featuredArticles.count是10。
所以基本上是-1 % 10,应该是9,但结果却是5。 Google说是9。
如果我执行NSInteger articleIndex = -1 % 10;,它会给我-1。
我尝试将count的NSUInteger转换为NSInteger,但不起作用。 我试图在各个地方插入括号,但也没用。
自那时起,我已经切换到使用((-1 % 10) + 10) % 10
但我仍然想知道这里的问题是什么。 有什么想法吗?
编辑:
featuredArticlesCounter是有符号整数
self.featuredArticles.count是无符号整数

@Kevin:那个问题没有解释为什么在这种情况下“-1%10”会产生5。这不是重复的问题。 - Eric Postpischil
@Kevin:unsigned short x = -1; printf("%d\n", x % 10); 输出结果为5。这可能是问题中的一个笔误,但在得出结论之前应该确定实际错误,而不是猜测,以免重复。 - Eric Postpischil
1
@EricPostpischil 是的,我发布后意识到2**32 - 1%10是5。 - Kevin
1
这与Xcode和iOS无关。 - user529758
那就是我观察到问题并认为它很相关的地方。 - Andrew
显示剩余2条评论
2个回答

6
featuredArticlesCounter 明显是一个无符号整数。当你认为它被设置为-1时,实际上你将其设置为了 2**32 - 1 (~0)。 这个数字除以10的余数是5。(显然,2**(8k)-1 % 10 是 5,所以它实际上是无关紧要的无符号整数的大小)。
至于为什么-1 % 10-1,我相信在C语言中,负数取模是实现定义的,但在这种情况下(如Java),它被定义为这样:x / y + x % y == x。如果你输入负数,-1 / 10 + -1 % 10 = -1 -> -1 % 10 = -1

观察到所有无符号长度都与5同余,+1。 - Nicholas Wilson
很不幸featuredArticlesCounter是一个有符号整数,而另一个是无符号的,但我不改变它的值。 - Andrew
2
这并不适用于所有的2的幂。(2^33 - 1)%10是1。当且仅当n是4的倍数且大于0时,2^n才成立,这使得它等价于(16^(n/4) - 1)%10。16的幂的最后一位数字总是6,因此减去1后,最后一位数字为5。 - ughoavgfhw
2
@ugohoavgfhw:注释中写着“所有无符号长度”,意在适用于现代系统,其中所有整数类型都是8位字节的倍数。而答案中写着“2 **(8k)”,因此仅适用于8的倍数幂次方。 - Eric Postpischil

3
也许硬件(或软件?)将数字作为无符号整数处理:
  1. -1 == 0xFFFFFFFF(采用二进制补码编码)

  2. 0xFFFFFFFF == 4294967295(假设原始数据是无符号整数)

  3. 4294967295 % 10 == 5(通过观察最后一位数字很容易得出)

这是我最好的猜测。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接