7

我正在阅读C Traps and PitfallsAndrew Koening 的书中关于 C 可移植性的部分。

在整数除法上

q = a/b;
r = a%b;

如果 a 是负数,显然提醒r可以是负数或正数,同时满足性质

q * b + r == a

通常,如果股息a为负,我预计r为负。这就是我在带有 gcc 的英特尔机器上看到的。我只是好奇你有没有见过当股息为负数时会返回积极提醒的机器?

4

1 回答 1

9

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 的符号。'' 此定义适用于所有实现。

于 2012-04-05T06:21:46.827 回答