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;
}
int modulo_Euclidean2(int a, int b) {
if (b == 0) TBD_Code(); // perhaps return -1 to indicate failure?
if (b == -1) return 0; // This test needed to prevent UB of `INT_MIN % -1`.
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;
}
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
7条答案
按热度按时间laik7k3q1#
模数和余数之间存在差异。例如:
-21
模4
等于3
,因为-21 + 4 x 6
等于3
。但是
-21
除以4
得到-5
,余数为-1
。对于正值,没有差异。
s6fujrry2#
在C语言中," %"是指"mod"还是"rem"?
在C中,
%
是余数1。...,
/
运算符的结果是去掉任何小数部分的代数商...(这通常被称为"向零截断")C11dr § 6.5.5 6%
运算符的操作数必须是整数类型。C11dr § 6.5.5 2/
运算符的结果是第一个操作数除以第二个操作数所得的商;%
运算符的结果是余数... C11dr § 6.5.5 5"模"和"余数"有什么区别?
C没有定义"mod"或"modulo"运算符/函数,例如Euclidean division或other modulo中使用的整数模函数。
C定义 * 余数 *。
让我们将每个
%
运算符的"余数"与欧几里德"mod"进行比较。当
a
为负时,"欧几里得mod"不同于C的a%b
运算。欧几里德除法中的"mod"或"modulo"。结果总是0或正数。
候选模代码:
关于浮点的注意事项:
double fmod(double x, double y)
,虽然称为"fmod",但它与欧几里德除法"mod"不同,而类似于C整数余数:fmod
函数计算x/y
的浮点余数。C11dr § 7.12.10.1 2Disambiguation:C也有一个类似的命名函数
double modf(double value, double *iptr)
,它将参数值分为整数和小数部分,每个部分都与参数具有相同的类型和符号,除了名称相似之外,这与这里讨论的"mod"没有什么关系。[Edit二○二○年十二月】
对于那些希望在所有情况下都能正常工作的用户,改进的
modulo_Euclidean()
可1)检测mod(x,0)
和2)使用modulo_Euclidean2(INT_MIN, -1)
获得良好的无UB结果。[1]在C99之前,C对
%
的定义仍然是除法的 * 余数 *,但是/
允许负商向下舍入,而不是"向零截断"。参见Why do you get different values for integer division in C89?。因此,在C99之前的一些编译中,%
代码可以像欧几里得除法"mod"一样工作。上面的modulo_Euclidean()
也可以使用这种替代的老式余数。y53ybaqx3#
余数的符号将与被除数的符号相同,并且模数的符号将与除数的符号相同。
余数只是两个整数之间算术除法后的剩余部分,而模是余数和除数符号相反时的和,以及余数和除数符号相同时算术除法后的剩余部分。
余额示例:
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,带负号,因此余数也带负号,除数也带负号。由于余数和除数的符号相同,因此结果与余数相同]
我希望这将清楚地区分余数和模。
zphenhs44#
在C和C++以及许多语言中,
%
是余数而不是模运算符。例如,在
-21 / 4
运算中,整数部分是-5
,小数部分是-.25
。余数是小数部分乘以除数,因此余数是-1
。JavaScript使用余数运算符并对此进行确认取模运算符就像你有一个“时钟”。想象一个圆,其值分别为0、1、2和3,分别位于12点、3点、6点和9点的位置。顺时针方向绕时钟步进商的次数会使我们得到取模运算的结果,或者,在我们的例子中,逆时针方向是负商,得到3。
**注意:**模始终与除数的符号相同,余数与商的符号相同。当除数和余数中至少有一个为负时,将它们相加即可得到模。
9gm1akwq5#
模,在模运算中,你所指的是剩余的值或算术除法后的剩余值。这通常被称为余数。%在C / C++中是形式上的余数运算符。例如:
剩下要讨论的是如何处理这个%运算的负输入。现代C和C++为这个运算生成一个有符号的余数值,其中结果的符号总是与被除数输入的符号匹配,而不考虑除数输入的符号。
dl5txlt96#
您可以通过以下关系式使用余数(%)编写自己的模函数
在n =(-7,7)和m = 3的范围内,求余数和模值之间的差值
vsnjm48y7#
在数学中,模运算的结果是欧几里德除法的余数。然而,其他的约定也是可能的。计算机和计算器有各种各样的存储和表示数字的方法;因此,它们对模运算的定义取决于编程语言和/或底层硬件。