"mod"和"remaining"之间有什么区别?

son*_*hir 116 c math operators

我的朋友说"mod"和"rest"之间存在差异.

如果是这样,那么C和C++的差异是什么?"%"是指C中的"mod"还是"rem"?

Dav*_*rtz 123

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

-21MOD 43因为-21 + 4 x 63.

-21除以4给出-5的剩余部分-1.

对于正值,没有区别.

  • %表示在C中的rem. (21认同)
  • @Jinxiao:在C89中它是实现定义的:`%`总是余数,但它也可能*是模数(即总是正数),因为在C89中,整数除法被允许向负无穷大而不是向0舍入所以在C89中,`-5/2`可以是`-2`,余数为-1,或者`-3`,余数为`1`,实现只需要记录哪个.C99删除了灵活性,所以现在`-5/2`总是`-2`. (20认同)
  • @OzEdri要获得一些数字mod 4,你可以添加4的整数倍,以获得0到3之间的数字.对于-21,该整数是6,因为`-21 + 4 x 6`介于0和3之间. (12认同)
  • 有人可以解释第一次计算中的步骤吗?怎么`-21` mod`4`是'3`?为什么计算是'-21 + 4 x 6`? (8认同)
  • 其实这是错误的。根据定义(参见 https://en.wikipedia.org/wiki/Euclidean_division)余数是一个正数,所以 `-21` 除以 `4` 得到 `-6` 余数为 `3` (4认同)
  • 实际上,目前尚不清楚模数是多少.根据上下文和语言,似乎有许多不同的定义.请参阅有关modulo_operation的维基百科文章.在某些情况下,它实际上与余数相同. (2认同)

chu*_*ica 37

"%"是指C中的"mod"还是"rem"?

在C中,%剩余1.

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

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

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


"mod"和"remaining"之间有什么区别?

C不定义"mod",例如欧几里德分区中使用的整数模数函数或其他模数."Euclidean mod"与C的a%b操作不同,当a为负时.

 // a % b
 7 %  3 -->  1  
 7 % -3 -->  1  
-7 %  3 --> -1  
-7 % -3 --> -1   
Run Code Online (Sandbox Code Playgroud)

模数为欧几里德分裂

 7 modulo  3 -->  1  
 7 modulo -3 -->  1  
-7 modulo  3 -->  2  
-7 modulo -3 -->  2   
Run Code Online (Sandbox Code Playgroud)

候选模数代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

关于浮点的注意事项: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   
Run Code Online (Sandbox Code Playgroud)

消歧:C也有一个类似的命名函数double modf(double value, double *iptr),它将参数值分解为整数和小数部分,每个部分与参数具有相同的类型和符号.除了名称相似性之外,这与"mod"讨论没什么关系.


1在C99之前,C的定义%仍然是除法的余数,然后/允许负商数向下舍入而不是"截断为零".请参阅为什么在C89中获得整数除法的不同值?.因此,通过一些C99之前的编译,%代码可以像欧几里德分区"mod"一样运行.上面的内容modulo_Euclidean()也适用于这个替代的老式学校.

  • 要在 C 中实现欧几里得除法和模函数,请参阅[计算机科学家的除法和模数](https://www.microsoft.com/en-us/research/publication/division-and-modulus-for-computer-scientists/ )。如果您只知道股息可以为负,但除数始终为正,则它可以运行得更快:https://godbolt.org/g/63UqJo。相关:[要求非负模的 x86 asm 问题](http://stackoverflow.com/questions/40861023/how-do-i-get-a-positive-modulo-on-a-negative-dividend) (2认同)

the*_*lon 6

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

例如,在运算中-21 / 4整数部分为-5,小数部分为-.25。余数是小数部分乘以除数,所以余数是-1。JavaScript 使用余数运算符并确认了这一点

console.log(-21 % 4 == -1);
Run Code Online (Sandbox Code Playgroud)

模运算符就像你有一个“时钟”。想象一个圆,其值分别为 0、1、2 和 3,分别位于 12 点钟、3 点钟、6 点钟和 9 点钟位置。顺时针绕时钟步进商时间可以得到模数运算的结果,或者在我们的负商示例中,逆时针步进,得到 3。

注意:模始终与除数的符号相同,余数与商的符号相同。当至少有一个为负时,将除数和余数相加即可得到模数。

  • 您的意思是余数的符号始终与*被除数*相同吗?`7 / -3 = -2` 的商,但是 `7 rem -3 = 1`。 (2认同)

小智 6

余数的符号将与可除数相同,模数的符号将与除数相同。

余数只是两个整数之间的算术除法后的剩余部分,而模数是余数和除数的和,当它们符号相反时,当余数和除数都具有相同的符号时,算术除法后的剩余部分。

余数示例:

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,它是负号的,所以余数也将是负号的,除数也是负号的。由于余数和除数的符号相同,结果将与余数相同]

我希望这将清楚地区分余数和模数。