我正在阅读C Traps and Pitfalls
Andrew Koening 的书中关于 C 可移植性的部分。
在整数除法上
q = a/b;
r = a%b;
如果 a 是负数,显然提醒r可以是负数或正数,同时满足性质
q * b + r == a
通常,如果股息a为负,我预计r为负。这就是我在带有 gcc 的英特尔机器上看到的。我只是好奇你有没有见过当股息为负数时会返回积极提醒的机器?
我正在阅读C Traps and Pitfalls
Andrew Koening 的书中关于 C 可移植性的部分。
在整数除法上
q = a/b;
r = a%b;
如果 a 是负数,显然提醒r可以是负数或正数,同时满足性质
q * b + r == a
通常,如果股息a为负,我预计r为负。这就是我在带有 gcc 的英特尔机器上看到的。我只是好奇你有没有见过当股息为负数时会返回积极提醒的机器?
C99 将余数形式化为与股息具有相同符号。在 C99(C89 和 K&R)之前,它可能会采取任何一种方式,因为两种结果都符合技术要求。在这件事上,确实有编译器不符合 C99 规范,尽管我不知道有任何编译器。
特别是,第 6.5.5 节(乘法运算符)指出:
¶5 / 运算符的结果是第一个操作数除以第二个操作数的商;% 运算符的结果是余数。在这两个操作中,如果第二个操作数的值为零,则行为未定义。
¶6当整数被除法时,
/
运算符的结果是代数商,其中任何小数部分被丢弃。87)如果商a/b
是可表示的,则表达式(a/b)*b + a%b
应等于a
。87)这通常被称为“向零截断”。
有了这个新定义,余数基本上被定义为你期望它在数学上是什么。
编辑
为了解决评论中的问题,C99 规范还指定(脚注 240)如果余数为零,则在没有符号零的系统上,r 的符号将与除数 x 的符号相同。
''当 y ≠ 0 时,余数 r = x REM y 由数学关系 r = x - ny 定义,与舍入模式无关,其中 n 是最接近 x/y 精确值的整数;每当| n - x/y | = 1/2,则 n 为偶数。因此,余数总是准确的。如果 r = 0,则其符号应为 x 的符号。'' 此定义适用于所有实现。