我的朋友说“mod”和“rest”之间存在差异。
如果是这样,那么C和C ++的差异是什么? “%”是指C中的“mod”还是“rem”?
答案 0 :(得分:113)
模数和余数之间存在差异。例如:
-21
mod 4
为3
,因为-21 + 4 x 6
为3
。
但-21
除以4
,-5
的余数为-1
。
对于正值,没有区别。
答案 1 :(得分:33)
'%'是指C中的“mod”还是“rem”?
在C中,%
是余数 1 。
...,
/
运算符的结果是代数商,丢弃了任何小数部分...(这通常称为“截断为零”。)C11dr§6.5.56
%
运算符的操作数应具有整数类型。 C11dr§6.5.52
/
运算符的结果是第一个操作数除以第二个操作数的商;%
运算符的结果是余数 ...C11dr§6.5.55
“mod”和“remaining”之间有什么区别?
C未定义“mod”,例如Euclidean division或other modulo中使用的整数模数函数。当a%b
为负时,“欧几里德模式”与C a
操作不同。
// a % b
7 % 3 --> 1
7 % -3 --> 1
-7 % 3 --> -1
-7 % -3 --> -1
Modulo as Euclidean division
7 modulo 3 --> 1
7 modulo -3 --> 1
-7 modulo 3 --> 2
-7 modulo -3 --> 2
候选模数代码:
int modulo_Euclidean(int a, int b) {
int m = a % b;
if (m < 0) {
// m += (b < 0) ? -b : b; // avoid this form: it is UB when b == INT_MIN
m = (b < 0) ? m - b : m + b;
}
return m;
}
注意浮点:double fmod(double x, double y)
,即使称为“fmod”,它与欧几里德除法“mod”不同,但类似于C整数余数:
fmod
函数计算x/y
的浮点余数。 C11dr§7.12.10.12
fmod( 7, 3) --> 1.0
fmod( 7, -3) --> 1.0
fmod(-7, 3) --> -1.0
fmod(-7, -3) --> -1.0
Disambiguation:C也有一个类似的命名函数double modf(double value, double *iptr)
,它将参数值分解为整数和小数部分,每个部分都与参数具有相同的类型和符号。除了名称相似性之外,这与“mod”讨论没什么关系。
1 在C99之前,C对%
的定义仍然是来自除法的余数,然后/
允许负商数向下舍入而不是“截断为零”。见Why do you get different values for integer division in C89?。因此,对于一些C99之前的编译,%
代码可以像欧几里德分区“mod”一样运行。上面的modulo_Euclidean()
也适用于这个替代的老派剩余部分。
答案 2 :(得分:4)
余数符号与可整除数相同,模数符号与除数相同。
余数只是两个整数之间的算术除法后的剩余部分,而模数是余数和除数的和,当它们符号相反时,算术除法后的剩余部分,当余数和除数同号时。
>余数示例:
10 % 3 = 1 [这里的可整除是 10,它是正号的,所以结果也将是正号的]
-10 % 3 = -1 [这里可以整除 -10,它是负号的,所以结果也将是负号的]
10 % -3 = 1 [这里可整除是 10,它是正符号,所以结果也将是正符号]
-10 % -3 = -1 [这里可以整除 -10,它是负号的,所以结果也将是负号的]
模数示例:
5 % 3 = 2 [这里的可整除是 5,它是正号的,所以余数也将是正号的,除数也是正号的。由于余数和除数同号,结果与余数相同]
-5 % 3 = 1 [这里可整除是-5,它是负号的,所以余数也将是负号的,而除数是正号的。由于余数和除数符号相反,结果将是余数和除数之和 -2 + 3 = 1]
5 % -3 = -1 [这里可整除是 5,它是正符号,所以余数也将是正符号,而除数是负符号。由于余数和除数符号相反,结果将是余数和除数之和 2 + -3 = -1]
-5 % -3 = -2 [这里可整除是 -5,它是负号的,所以余数也将是负号的,除数也是负号的。由于余数和除数同号,结果与余数相同]
我希望这能清楚地区分余数和模数。
答案 3 :(得分:2)
模数,在你所指的模运算中,是算术除法后的剩余值或剩余值。这通常称为余数。 %正式是C / C ++中的余数运算符。例如:
7 % 3 = 1 // dividend % divisor = remainder
讨论的内容是如何处理此%操作的负输入。现代C和C ++为此操作生成带符号的余数值,其中结果的符号始终与被除数输入匹配,而不考虑除数输入的符号。
答案 4 :(得分:2)
% is a remainder(leftover after dividend / divisor) NOT modulus.
您可以使用关系的余数(%)编写自己的模数函数
((n%m)+m)%m
where `n` is the given number and `m` is the modulus
在下面找出范围 n = (-7,7) 和 m = 3 的余数和模值之间的差异
n -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7
-------------------------------------------------------------------------
%(-m) -1 0 -2 -1 0 -2 -1 0 1 2 0 1 2 0 1 => remainder
% m -1 0 -2 -1 0 -2 -1 0 1 2 0 1 2 0 1 => remainder
mod m 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 => ((n%m)+m)%m
mod(-m) -1 0 -2 -1 0 -2 -1 0 -2 -1 0 -2 -1 0 -2 => ((n%m)+m)%m
要记住的提示:
n%(-m) = +(remainder)
(-n)%(m) = -(remainder)
sign of 'm' doesn't matter
n mod (-m) = -(result)
(-n) mod m = +(result)
sign of 'n' doesn't matter
For +ve 'n' and '%(-m)' or '%m' or 'mod m' gives the same remainder
答案 5 :(得分:0)
在C和C ++以及许多语言中,%
是余数而不是模运算符。
例如,在操作-21 / 4
中,整数部分为-5
,小数部分为-.25
。余数是除数的小数部分,因此我们的余数是-1
。 JavaScript使用剩余运算符并确认
console.log(-21 % 4 == -1);
模数运算符就像您有一个“时钟”。想象一个分别在12点,3点,6点和9点位置的值分别为0、1、2和3的圆。顺时针步进商时间使我们依赖于模运算的结果,或者在我们的示例中为负商时,逆时针为3。
注意:模数始终与除数相同,而余数与商相同。当余数中的至少一个为负数时,除数和余数将产生模量。
答案 6 :(得分:-1)
在数学中,模运算的结果是欧几里德分裂的其余部分。但是,其他惯例也是可能的。计算机和计算器有各种存储和表示数字的方式;因此,他们对模运算的定义取决于编程语言和/或底层硬件。
7 modulo 3 --> 1
7 modulo -3 --> -2
-7 modulo 3 --> 2
-7 modulo -3 --> -1