C中的签名除法 [英] signed division in C
问题描述
我正在阅读安德鲁·科宁(Andrew Koening)在书C Traps and Pitfalls
中有关C可移植性的部分.
I was reading the section on C portability in the book C Traps and Pitfalls
by Andrew Koening..
以整数除法
q = a/b;
r = a%b;
如果a是一个负数,则提醒 r 显然可以是一个负数或正数,同时满足属性
If a is a negative number, apparently the reminder r can be a negative or positive number, while satisfying the property
q * b + r == a
通常,我期望 r 为负,如果分红 a 为负.这就是我在带有gcc的intel机器中看到的.我很好奇,您是否曾经见过一台在股息为负数时会返回正提醒的机器?
Normally I would expect r to be negative if dividend a is negative. And that is what I see in a intel machine with gcc. I am just curious have you ever seen a machine that would return a positive reminder when the dividend is a negative number ?
推荐答案
C99将其余部分形式化为与股息相同的符号.在C99(C89和K& R)之前,由于两种结果均满足技术要求,因此可以采用任何一种方法.确实有一些不符合C99规范的编译器,尽管我不知道有什么问题.
C99 formalized the remainder as having the same sign as the dividend. Prior to C99 (C89 and K&R), it could have gone either way as both results meet the technical requirements. There are indeed compilers out there non-conforming to the C99 spec in this matter, though I don't know of any off the top of my head.
尤其是,第6.5.5节(乘法运算符)指出:
In particular, section 6.5.5 (Multiplicative operators) states:
¶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当整数相除时,/
运算符的结果是代数商,其中任何
87)如果商a/b
是可表示的,则表达式
(a/b)*b + a%b
应等于a
.
¶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)这通常被称为向零截断".
87) This is often called "truncation toward zero".
有了这个新定义,其余的基本上定义为您希望它在数学上说的话.
With this new definition, the remainder is basically defined as what you'd expect it to be mathematically speaking.
编辑
要解决注释中的问题,C99规范还指定(脚注240),如果余数为零,则在未签名零的系统上,r的符号将与除数x.
To address a question in the comments, the C99 spec also specifies (footnote 240) that if the remainder is zero, on systems where zero is not signed the sign of r will be the same as that of divisor, x.
’‘当y≠0时,不管 通过数学关系r = x − ny的舍入模式,其中n是 最接近x/y确切值的整数;每当n − x/y | = 1/2, 那么n是偶数因此,余数始终是精确的. 如果r = 0,则其 符号应为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中的签名除法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!