关于C#:Obj中的怪异mod行为。 C

 2020-06-06 

Weird mod behavior in Obj. C

我有以下代码:

1
2
NSInteger index1 = (stop.timeIndex - 1);  //This will be -1
index1 = index1 % [stop.schedule count];  // [stop.schedule count] = 33

所以我的表达式为-1%33。这应该给我32,但是给了我3 ...我已经在调试器中仔细检查了值。 有人有什么想法吗?


在C语言中,模数运算符不适用于负数。 (它给出了余数,而不是通用名称所暗示的那样进行模块化算术。)


C99在6.5.5节"乘法运算符(粗体)"中说:

The result of the / operator is the quotient from the division of the first operand by the
second; the result of the % operator is the remainder. In both operations, if the value of
the second operand is zero, the behavior is undefined.

When integers are divided, the result of the / operator is the algebraic quotient with any
fractional part discarded. If the quotient a/b is representable, the expression
(a/b)*b + a%b shall equal a.

它说%是余数,并且不使用"模数"一词来描述它。实际上,"模数"一词仅出现在我的C99副本中的三个位置,所有这些都与库有关,而与任何运算符无关。

它没有说任何要求其余部分为正的内容。如果需要正余数,则将a%b重写为(a%b + b) % b将对ab的符号起作用,并给出肯定的答案,但要付出额外的加法和除法运算。将其计算为m=a%b; if (m<0) m+=b;可能会更便宜,具体取决于目标架构中丢失的分支或额外的划分是否更便宜。

编辑:我对Objective-C一无所知。您的原始问题被标记为C,到目前为止的所有答案都反映了C语言,尽管您的示例似乎是Objective-C代码。我假设了解C的真实情况会有所帮助。


在负数上使用mod运算符的结果通常是意外的。例如,这:

1
2
3
4
5
6
7
#include <stdio.h>

int main() {
    int n = -1 %  33;
    printf("%d\
"
, n );
}

用GCC产生-1,但我不明白为什么您期望表达式的计算结果为32-这样就可以了。通常最好不要执行此类操作,尤其是如果您希望代码具有可移植性。