C remainder/modulo 正参数的运算符定义
C remainder/modulo operator definition for positive arguments
我在我应该修复的程序中发现了一个函数,它定义了一个 mod
函数:
int mod(int a, int b)
{
int i = a%b;
if(i<0) i+=b;
return i;
}
我被告知 a
和 b
将永远是积极的...
嗯? if(i<0)
?
参数是,that
the result of the modulo operation is an equivalence class, and any member of the class may be chosen as representative
而且只是事后才想到的
...; however, the usual representative is the least positive residue, the smallest nonnegative integer that belongs to that class, i.e. the remainder of the Euclidean division. However, other conventions are possible.
这意味着 6 % 7
可以 return 6
(到目前为止还不错),而且 -1
。嗯……真的吗? (让我们忽略所提供的实现并不能处理所有情况的事实。)
我知道模运算在数学上是这样的。但后来有人告诉我,C %
实际上确实 "not implement the modulo operator but the remainder"。
那么,C是如何定义%
运算符的呢?
在C-Draft中我只找到
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 % 7
总是 6
?还是也可以-1
?
Does this mean, that 6 % 7 is always 6? Or can it be -1, too?
Remainder
The binary operator % yields the remainder of the division
of the first operand by the second (after usual arithmetic
conversions).
[...]
when the type after usual arithmetic conversions is an integer type,
the result is the algebraic quotient (not a fraction), rounded in
implementation-defined direction (until C99)truncated towards zero
(since C99)
所以6 / 7
将是0
,而6 % 7
将是6 - 0
,即6
。
关于模运算和等价 classes 的声明很有趣,但在 C(和大多数其他编程语言)中不是这样工作的。
而且,就算是这样,-8
不也是等价的class吗?那么if(i<0) i+=b;
也解决不了问题
But then someone else told me that the C % does in fact "not implement
the modulo operator but the remainder".
说得好。在我链接的文档中,它被称为 "Remainder".
按照标准:
When integers are divided, the result of the /
operator is the
algebraic quotient with any fractional part discarded. If the quotient
a/b is representable, the expression (a/b)*b + a%b
shall equal a
.
[ISO/IEC 9899:2011: 6.5.5]
这意味着a
的符号保留在模数中。
17 % 3 -> 2
17 % -3 -> 2
-17 % 3 -> -2
-17 % -3 -> -2
所以不,6%7
不能是 -1
因为提醒必须有相同的红利符号。
永远:
a == (a/b)*b + a%b
abs(a%b) < abs(b)
- 如果
a
和 b
为正数,则 a % b
为正数。
从 C99 开始,
a/b == trunc(a/b)
a%b
是 0
或具有 a
的符号。
认为 6 % 7
可能是 -1
可能是因为忽略了 a
和 b
阳性的结果始终得到保证这一事实并且错过了变化在 C99 中。
当一个数或另一个可能为负数时,至少有三种不同的方法来定义除法和余数算法。 (有关详细信息,请参阅 this Wikipedia article -- and particularly the nice picture there。)
但是如果你知道你是用一个正数除以一个正数,那就没有任何歧义了。除法和余数的所有三个定义都表示,如果您将正数除以正数,则会得到正商和正余数。
在那里的三个选项中,C 使用了一个名为 "truncating division" 的选项。但是,同样,对于正数,它没有任何区别。 (曾几何时,由编译器决定是使用截断还是 "Euclidean" 除法,但事情只在一个定义上解决了,之前对 C 标准进行了几次修订。)
Does this mean, that 6 % 7
is always 6
? Or can it be -1
, too?
是的,6 % 7
总是 6(在 C 中,以及在任何三种定义下)。
另见 。
我在我应该修复的程序中发现了一个函数,它定义了一个 mod
函数:
int mod(int a, int b)
{
int i = a%b;
if(i<0) i+=b;
return i;
}
我被告知 a
和 b
将永远是积极的...
嗯? if(i<0)
?
参数是,that
the result of the modulo operation is an equivalence class, and any member of the class may be chosen as representative
而且只是事后才想到的
...; however, the usual representative is the least positive residue, the smallest nonnegative integer that belongs to that class, i.e. the remainder of the Euclidean division. However, other conventions are possible.
这意味着 6 % 7
可以 return 6
(到目前为止还不错),而且 -1
。嗯……真的吗? (让我们忽略所提供的实现并不能处理所有情况的事实。)
我知道模运算在数学上是这样的。但后来有人告诉我,C %
实际上确实 "not implement the modulo operator but the remainder"。
那么,C是如何定义%
运算符的呢?
在C-Draft中我只找到
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 % 7
总是 6
?还是也可以-1
?
Does this mean, that 6 % 7 is always 6? Or can it be -1, too?
Remainder
The binary operator % yields the remainder of the division of the first operand by the second (after usual arithmetic conversions).
[...]
when the type after usual arithmetic conversions is an integer type, the result is the algebraic quotient (not a fraction), rounded in implementation-defined direction (until C99)truncated towards zero (since C99)
所以6 / 7
将是0
,而6 % 7
将是6 - 0
,即6
。
关于模运算和等价 classes 的声明很有趣,但在 C(和大多数其他编程语言)中不是这样工作的。
而且,就算是这样,-8
不也是等价的class吗?那么if(i<0) i+=b;
也解决不了问题
But then someone else told me that the C % does in fact "not implement the modulo operator but the remainder".
说得好。在我链接的文档中,它被称为 "Remainder".
按照标准:
When integers are divided, the result of the
/
operator is the algebraic quotient with any fractional part discarded. If the quotient a/b is representable, the expression(a/b)*b + a%b
shall equala
. [ISO/IEC 9899:2011: 6.5.5]
这意味着a
的符号保留在模数中。
17 % 3 -> 2
17 % -3 -> 2
-17 % 3 -> -2
-17 % -3 -> -2
所以不,6%7
不能是 -1
因为提醒必须有相同的红利符号。
永远:
a == (a/b)*b + a%b
abs(a%b) < abs(b)
- 如果
a
和b
为正数,则a % b
为正数。
从 C99 开始,
a/b == trunc(a/b)
a%b
是0
或具有a
的符号。
认为 6 % 7
可能是 -1
可能是因为忽略了 a
和 b
阳性的结果始终得到保证这一事实并且错过了变化在 C99 中。
当一个数或另一个可能为负数时,至少有三种不同的方法来定义除法和余数算法。 (有关详细信息,请参阅 this Wikipedia article -- and particularly the nice picture there。)
但是如果你知道你是用一个正数除以一个正数,那就没有任何歧义了。除法和余数的所有三个定义都表示,如果您将正数除以正数,则会得到正商和正余数。
在那里的三个选项中,C 使用了一个名为 "truncating division" 的选项。但是,同样,对于正数,它没有任何区别。 (曾几何时,由编译器决定是使用截断还是 "Euclidean" 除法,但事情只在一个定义上解决了,之前对 C 标准进行了几次修订。)
Does this mean, that
6 % 7
is always6
? Or can it be-1
, too?
是的,6 % 7
总是 6(在 C 中,以及在任何三种定义下)。
另见