C 中的有符号除法

2024-03-01

我正在阅读书中有关 C 可移植性的部分C Traps and Pitfalls安德鲁·科尼格..

关于整数除法

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

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

q * b + r == a

通常我会期望r如果股息为负a是负数。这就是我在带有 gcc 的 intel 机器上看到的。我只是好奇你见过当股息为负数时会返回正提醒的机器吗?


C99 将余数形式化为与被除数具有相同的符号。在 C99(C89 和 K&R)之前,它可以采用任何一种方式,因为两种结果都满足技术要求。在这个问题上,确实存在不符合 C99 规范的编译器,尽管我不知道有什么编译器是这样的。

特别是,第 6.5.5 节(乘法运算符)指出:

¶5 / 运算符的结果是除以的商 第一个操作数由第二个操作数组成; % 运算符的结果是 余。在这两个操作中,如果第二个操作数的值为 零,行为未定义。

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

87) This is often called "truncation toward zero".

通过这个新定义,余数基本上被定义为您期望的数学上的值。

EDIT

为了解决评论中的问题,C99 规范also指定(脚注 240)如果余数为零,则在零没有符号的系统上,r 的符号将与除数 x 的符号相同。

‘当 y ≠ 0 时,余数 r = x REM y 的定义与 通过数学关系 r = x − ny 进行舍入模式,其中 n 是 最接近 x/y 精确值的整数;每当 | n-x/y| = 1/2, 那么n是偶数。因此,余数总是准确的。如果 r = 0,则其 符号应为x。”这个定义适用于所有 实施。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 中的有符号除法 的相关文章