c - C 中的签名除法

标签 c portability division

我正在阅读 Andrew Koening 所著的 C Traps and Pitfalls 一书中关于 C 可移植性的部分。

整数除法

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

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

q * b + r == a

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

最佳答案

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

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

¶5 The result of the / operator is the quotient from the division of the first operand by the second; the result of the % operator is the remainder. In both operations, if the value of the second operand is zero, the behavior is undefined.

¶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".

有了这个新定义,余数基本上被定义为您在数学上所期望的。

编辑

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

‘‘When y ≠ 0, the remainder r = x REM y is defined regardless of the rounding mode by the mathematical relation r = x − ny, where n is the integer nearest the exact value of x/y; whenever | n − x/y | = 1/2, then n is even. Thus, the remainder is always exact. If r = 0, its sign shall be that of x.’’ This definition is applicable for all implementations.

关于c - C 中的签名除法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10023440/

相关文章:

objective-c - 在一个库中声明变量或函数并在另一个库中定义它

c++ - 使用静态 SFML 库时无法链接我的项目

python - 如何在 numpy 中将一个数组除以另一个数组元素?

c - C中的二进制整数除法?

c - 创建线程时出错。警告 : passing argument 3 of ‘pthread_create’ from incompatible pointer type

c - gcc编译器在编译时在哪里寻找头文件?

c++ - 在 Linux 中是否有将 wstring 或 wchar_t* 转换为 UTF-8 的内置函数?

c - 删除 C 中的多字符常量

Windows 等同于 Linux namespace (每个进程文件系统挂载)?

erlang - 整数除法