【问题标题】:modulo operation on negative numbers [duplicate]负数的模运算
【发布时间】:2015-07-23 20:02:05
【问题描述】:

模运算 a%b 返回 a/b 的余数,但对于负数则不这样做。

#include <stdio.h>

int main(void) {
  int n=-4;
  printf("%d\n",n%3);
  return 0;
}

它应该返回 2,因为 3*(-2)=-6 小于 -4 并且是 3 的倍数,但输出为 -1。 为什么它对待(-a) mod b-(a mod b) 一样

【问题讨论】:

  • 因为模组就是这样工作的? -4 % 3 === -1,不是-2
  • 如果你尝试将 -4 分成 3 份,你会得到 3 份尺寸 -1 和 1 份你无法分割的尺寸 -1。 (也就是说,如果结果为 +2 且 -4/3 的结果为 -2,则它会更有用,但我们坚持返回 -1。)
  • 请注意,“-4 减去 -6”等于“-4 加上 +6”等于“+2”而不是“-2”。不,数学规则始终适用:就像“+4 模 3”等于“+1”一样,“-4 模 3”等于“-1”。

标签: c modulo negative-number


【解决方案1】:

作为一般规则,模和除应满足方程

b * (a/b) + a%b == a

对于正数,很明显这意味着a%b 必须是正数。但如果a/b 为负数,则结果将向零舍入。

所以以 a = -4, b = 3 为例。我们知道 a/b = -1.3333,向零舍入变为a/b == -1。从上面的等式,我们得到b * (-1) + a%b == a。如果我们插入ab,我们得到-3 + a%b == -4,我们看到a%b 必须是-1。

【讨论】:

    【解决方案2】:

    您的痛苦源于接受% 是“模”运算符的错觉。事实上,它是一个余数运算符(C11 §6.5.5):

    / 运算符的结果是除法的商 第二个操作数的第一个操作数; % 运算符的结果是 余数

    拒绝幻想,接受真相,操作者的行为就会变得清晰(同上):

    如果商a/b 是可表示的,则表达式(a/b)*b + a%b 应等于a

    在您的情况下,a/b-4/3,即 -1,因此是可表示的。所以a%b满足:

    (a/b)*b + a%b =  a
    (-1)*3  + a%b = -4
      -3    + a%b = -4
              a%b = -1
    

    【讨论】:

    • 奇怪...我认为模的数学定义是“余数”。
    • @MikeRobinson:在计算方面确实如此。但这会让那些期望余数 a%b 在随意的数学意义上是“模 b”的人感到困惑(这取决于你问的是谁,要么是严格正数,要么与 b 的符号匹配,而不是 a) .
    • 这里的问题是,对于 C / C++,整数除法向零舍入,因此余数为零或与被除数具有相同符号,而在数学和其他一些编程语言中,整数除法向零舍入负无穷大,所以余数为零或与除数的符号相同。
    猜你喜欢
    • 2021-03-20
    • 2011-04-22
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    相关资源
    最近更新 更多