c89和c99中的余数运算符
c99标准规定模运算的结果和第一个操作数的符号相同。所以c89和c99中的余数运算符,c,c99,c89,C,C99,C89,c99标准规定模运算的结果和第一个操作数的符号相同。所以-9%7=-2和9%-7=2 我在一本书中读到c89标准依赖于实现。因此-9%7可以产生-2或5???-9/7的剩余部分如何成为5?考虑两个数字a和b 商q=a/b和余数r=a%b满足等式a==q*b+r C89的一个(假设的)实现,其中-9%7产生5,是一个实现,其中-9/7被计算为-2 数学(欧几里德)除法将r限制为正,小于b。C99将其限制为与a具有相同的符号,并且严格限制在-b和b之间。 这只是一个惯例。%运算符的定义如下: a =
-9%7=-2
和9%-7=2
我在一本书中读到c89标准依赖于实现。因此
-9%7
可以产生-2
或5
???-9/7
的剩余部分如何成为5
?考虑两个数字a
和b
商q=a/b
和余数r=a%b
满足等式a==q*b+r
C89的一个(假设的)实现,其中-9%7产生5,是一个实现,其中-9/7被计算为-2
数学(欧几里德)除法将r
限制为正,小于b
。C99将其限制为与a
具有相同的符号,并且严格限制在-b
和b
之间。
这只是一个惯例。
%
运算符的定义如下:
a == (a / b * b) + a % b
所以
%作为余数运算符
如果/
朝0
方向旋转(如C99):
您有-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
-2x7+5=-9。我认为这是逻辑。如果整数除法不截断而是“向下舍入”(接近-无穷大),那么这是合理的,不是吗?@H2CO3我在一个静态分析器上工作,其中可能的值集可以总结为同余信息(例如:“在这一行的这个程序中,
x
的所有值都等于1模3”)。分析器使用欧几里德除法,因为它具有最好的代数性质,但我对C99(实际上是处理器)发了牢骚更容易实现,但代数选择次数更少。我明白了,但1.我认为抱怨标准没有多大意义,它的编写是为了易于实现(否则你会如何解释所有未定义的行为?)2.在我看来,允许这一点是合乎逻辑的,我不认为强制整数除法向0取整是个好主意。@H2CO3我认为你的观点1.和2.解释C89中的选择(他们试图让每个人都高兴).在C99中,他们一定已经看到并意识到每个硬件实现都在执行截断,因此标准也可以这样指定除法。带截断的除法更容易在硬件中实现,因为结果的符号和绝对值可以并行计算。@H2CO3因为在尝试编写C程序时不能假定除法以这种或那种方式工作是一种痛苦。更极端的立场是“为什么要在标准中指定除法?为什么不把它作为(实际上)所有编译器都会有的编译器特定扩展?”?答案是,像C这样的语言标准是一种折衷,既允许在实现中留有余地,又允许程序员在编译时不必检测除法行为而简洁、可移植地编程。如果/舍入到负无穷大,那么从C99开始,该行为就被标准禁止了,对吗?
-9 % 7 == 5
-9 % 7 == -9 - (-9 / 7 * 7) + 9 == -9 + 14 == 5