C89和C99中的余数运算符

5
标准规定取模运算的结果与第一操作数符号相同。所以-9 % 7 = -2以及9 % -7 = 2

我在一本书中读到标准依赖于实现。所以-9 % 7可能得到-2或者5???如何使-9 / 7的余数为5


1
-2 X 7 + 5 = -9。我认为这是逻辑正确的。 - Juan
1
请参见 http://en.wikipedia.org/wiki/Modulo_operation。 - Pubby
2个回答

7
考虑两个数字a和b。 商q=a/b和余数r=a%b满足方程a == q*b + r。 一个(假想的)实现C89,其中-9%7产生5是一个实现,在其中计算-2为-9 / 7。 数学(欧几里德)除法要求r为正且小于b。 C99要求它与a具有相同的符号,并严格在-b和b之间。这仅仅是一种约定。

如果整数除法不是截断,而是“向下舍入”(朝负无穷方向),那么这很合理,不是吗? - user529758
我明白,但是1. 抱怨标准没有太多意义,因为它的编写是为了易于实现(否则你如何解释所有未定义的行为?)2. 对我来说,这似乎是合理的,我不认为强制整数除法向0舍入是一个好主意。 - user529758
@H2CO3,我认为你的第1点和第2点解释了C89的选择(他们试图让每个人都满意)。在C99中,他们必须看到并意识到每个硬件实现都在进行截断,因此标准也可以指定这种方式的除法。带有截断的除法在硬件中更容易实现,因为结果的符号和绝对值可以并行计算。 - Pascal Cuoq
当然,实现起来更容易,事实上我也这样做,但为什么不让别人有不同的选择呢? - user529758
1
因为在编写C程序时,不能假设除法按照某种方式工作是很痛苦的。更极端的立场是“为什么要在标准中指定除法?为什么不将其作为编译器特定扩展留下来(实际上)所有编译器都会有?”答案是,像C这样的语言标准是在允许实现方面做出妥协的同时,允许程序员在不必检测编译时除法行为的情况下编写简洁且可移植的程序。 - Pascal Cuoq
显示剩余2条评论

5

% 运算符的定义如下:

a == (a / b * b) + a % b

所以
a % b = a - (a / b * b)

作为余数运算符的 %
如果 / 操作按照向 0 取整的方式进行(如 C99):
-9 % 7 == -2

您有一个表达式-9 / 7 == -1,因此%的结果是-2,因为:
-9 % 7 == -9 - (-9 / 7 * 7) + 9 == -9 + 7 == -2 

作为取模运算符的%
如果/向负无穷取整:
-9 % 7 == 5

您有一个表达式-9 / 7 == -2,所以%的值为5

-9 % 7 == -9 - (-9 / 7 * 7) + 9 == -9 + 14 == 5

如果/向负无穷舍入,这种行为从C99标准开始就被禁止了,对吧? - Max Barraclough

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