“ mod”和“ remainder”有什么区别?


133

我的朋友说“ mod”和“ remainder”之间有区别。

如果是这样,C和C ++有哪些区别?'%'在C语言中是“ mod”还是“ rem”?


2
对于负操作数,可能定义不正确。
Basile Starynkevitch

1
我不是C人:(所以不能在答案框中真正回答这个问题。但是,请看一下这篇文章:)
bonCodigo 2012年

1
%是余数。答细节在这里- > blogs.msdn.com/b/ericlippert/archive/2011/12/05/...
WIM

1
在您精确定义术语含义之前,问题无任何意义。
David Heffernan

14
@David:问题是关于术语的含义。如果您说这个问题没有意义,尽管有几个人以发问者的意图理解了这个问题,那么我认为您必须更具体地表达“均值”一词的意思;-)
史蒂夫·杰索普

Answers:


140

模数和余数之间存在差异。例如:

-21mod 43因为-21 + 4 x 6is 3

-21除以4给出-5的余数-1

对于正值,没有区别。


22
%手段REM中C.
banuj

22
@Jinxiao:在C89是实现定义的:%总是其余的,但它可能有模量(即总为正),因为在C89整数除法被允许轮接近负无穷大的,而不是朝着0,所以在C89,-5 / 2可能-2与其余部分一起使用-1,或者-3与其余部分一起使用1,该实现只需要记录一下。C99取消了灵活性,因此-5 / 2始终如此-2
史蒂夫·杰索普

2
实际上,尚不清楚模数是多少。取决于上下文和语言,似乎有许多不同的定义。请参阅有关modulo_operation的维基百科文章。在某些情况下,它实际上与其余部分相同。
鲁迪·韦尔特胡斯

9
有人可以解释第一次计算中的步骤吗?如何-21MOD 43?为什么计算-21 + 4 x 6呢?
奥兹·埃德里

13
@OzEdri为了得到一些数量国防部4,你添加任何的4整数倍才能到达0和3之间的数字为-21,该整数是6,因为-21 + 4 x 6是介于0和3
大卫·施瓦兹

47

'%'在C语言中是“ mod”还是“ rem”?

在C中,%余数1

...,/运算符的结果是代数商,舍弃了任何小数部分...(这通常称为“向零截断”。)C11dr§6.5.56

运算%符的操作数应为整数类型。C11dr§6.5.52

/运算符的结果是第一个操作数除以第二个的商。%运算符的结果是余数 ... C11dr§6.5.55


“ mod”和“ remainder”有什么区别?

C没有定义“ mod”,例如在欧几里得除法其他模中使用的整数模函数。a%ba为负数时,“欧几里德mod”不同于C的运算。

 // a % b
 7 %  3 -->  1  
 7 % -3 -->  1  
-7 %  3 --> -1  
-7 % -3 --> -1   

模为欧几里得除法

 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   

歧义消除:C还具有类似的命名函数double modf(double value, double *iptr),该函数将参数值分为整数和小数部分,每个部分的类型和符号均与参数相同。除了名称相似外,这与此处的“ mod”讨论无关。


1在C99之前,C的定义%仍然是除法运算的余数,但随后/允许负商舍入而不是“截断为零”。请参阅为什么在C89中整数除法会得到不同的值?。因此,在C99之前的版本中,%代码可以像欧几里得分部“ mod”一样工作。上面的方法modulo_Euclidean()也可以与其他替代的老式方法一起使用。


1
要在C中实现欧几里得除法和模函数,请参阅《计算机科学家的除法和模量》。如果您仅知道股息可以为负,但是除数始终为正,则它可以运行得更快:godbolt.org/g/63UqJo。相关:一个要求非负模数的x86 asm问题
Peter Cordes

模运算符的通常定义更像是:
Mike Housky

2

模数,在您所指的模块化算术中,是算术除后的剩余值或剩余值。这通常称为余数。%正式是C / C ++中的余数运算符。例:

7 % 3 = 1  // dividend % divisor = remainder

剩下要讨论的是如何处理%操作的负输入。现代C和C ++为此操作生成一个带符号的余数,其中结果的符号始终与除数输入匹配,而与除数输入的符号无关。


1

在C和C ++和许多语言中,%余数不是模数运算符。

例如,在运算中-21 / 4,整数部分是-5,小数部分是-.25。余数是除数的小数部分,因此我们的余数是-1。JavaScript使用剩余运算符并确认

console.log(-21 % 4 == -1);

模运算符就像您有一个“时钟”。想象一个分别在12点,3点,6点和9点位置的值分别为0、1、2和3的圆。将商时间沿时钟方向顺时针步进使我们落在模运算的结果上,或者在我们的示例中为负商时,逆时针旋转,得出3。

注意:模数始终与除数相同,而余数与商相同。当余数中的至少一个为负数时,将除数和余数相加会得出模量。


-2

在数学中,模运算的结果是欧几里得除法的余数。但是,其他约定也是可能的。计算机和计算器具有多种存储和表示数字的方式;因此,它们对模运算的定义取决于编程语言和/或底层硬件。

 7 modulo  3 -->  1  
 7 modulo -3 --> -2 
-7 modulo  3 -->  2  
-7 modulo -3 --> -1 

2
维基欧几里德部门0 ≤ r < |b|,这意味着其余又名“模操作。” 始终至少为0。您使用什么定义得出-2和-1?
chux-恢复莫妮卡

先生,我不会,不过我只是Google 7模-3-> -2 .and.-7模-3-> -1请解释先生为什么会这样
shub sharma

1
Google使用与Wiki欧几里得除法不同的模(带符号模?)定义(如Raymond T. Boute所述)。 将进一步讨论差异。故事的寓意:a%b和正面a modulo b时具有相同的含义a,b。C99 %用负值精确定义。C调用这个“剩女”。‘模’已在世界有关负值各种定义C时的参数仅使用。‘在正数的情况下模。’
chux -恢复莫妮卡
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.