理解取模运算符的结果: %%

22

我正在尝试理解R语言中的%%运算符的工作原理:

10 %% 10  # 0
20 %% 10  # 0

我对这两个结果不太确定:

10 %% 20  # 10
2 %% 8  # 2

你能帮我理解最后两个结果吗?我有点困惑。


4
虽然Zhenyuan Li提供了一个不错的答案,但我认为你混淆了参数的顺序。如果你希望 10 %% 20 返回0,你实际上可能想要执行的是 20 %% 10 - Benjamin
https://en.wikipedia.org/wiki/Modulo_operation#Remainder_calculation_for_the_modulo_operation - nrussell
5个回答

31

没什么问题:

10 = 1 * 10 + 0
20 = 2 * 10 + 0
10 = 0 * 20 + 10
2  = 0 * 8  + 2 

取模运算是在加号后面的数字。


一般来说,对于两个数字 ab,有

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

让我们写一个玩具函数:

foo <- function(a,b) c(quotient = floor(a / b), modulo = a %% b)

foo(10, 10)
#quotient   modulo 
#   1        0 

foo(20, 10)
#quotient   modulo 
#   2        0 

foo(10, 20)
#quotient   modulo 
#   0       10 

foo(2, 8)
#quotient   modulo 
#   0        2 

更新:我们可以使用 a %/% b 来获取商,而不是使用 floor(a / b)


8

我将提供另一个解释。拿这个问题举例:

20 %% 10 = 0

不要计算模数,而是从简单的除法开始:

20 / 10 = 2

如您所知,“2”这个答案意味着需要两组10才能组成20。请注意,我们也可以用小数“2.0”来表示这个答案。

小数很重要。当小数为.0时,就没有余数了,我们有完整的组。如果除法产生一个0小数,那么模运算结果是0。

现在考虑一下这个问题:

11/3 = 3.667

那个尾数部分,即0.667,是在我们组成所有完整的三个数集之后剩余的3个数中的一部分。小数点左边的数字表示:
#Splitting the answer into its components - 3 full sets, 0.667 partial sets
3.0 + 0.667 = 3.667

如果我们想要知道实际剩余的数量,我们可以将0.667乘以除数3:

0.667 * 3 = 2

这是余数。它是在所有完整的3组形成后剩余下来的数量。这与使用模运算得到的结果相同:
11 %% 3 = 2

同样适用于这里。鉴于这个问题,
10 %% 20 = 10

我们可以正常地分割并得到:
10 / 20 = 0.5

读出来,我们有0个完整的20人小组(左边);我们只有半套20人(即0.5个)。

0.5 * 20 = 10

这相当于:
10 %% 20 = 10

因此,10就是余数。它是我们所拥有的10和到达20所需的10之间的差距。


4

我也曾经很困惑,但如果你明白%%运算符的结果是除法的余数,这就非常容易理解了。

例如:75%%4 = 3

我注意到如果被除数小于除数,那么R将返回相同的被除数值。

例如:

4%%75 = 4
10 %% 20  = 10
2 %% 8  = 2

division parts


1
尝试理解R中x模y的一些结果,我找到了这个页面。然后,为了解释一些“古怪”的结果,我编写了下面的R脚本。我曾经读到过模运算符的余数或结果应该始终为正数,但在R中并非如此,这里提供的定义和示例解释了似乎使用的逻辑。定义为x mod y = x - ( |_x/y_| * y),其中|_x/y_| = floor(x/y)在R中似乎总是成立,或者更标准地说,操作q = x / y的余数r的定义是x = k*q + r,其中kr都是整数。

基本上,在R中,当x = 2y = -5时,x mod y = -3;或者使用定义x = k*q + r,我们有r = x - k*q = -3

然而,从数学角度来看,这有点古怪,因为“整数部分乘积” (k*q) 实际上超过了被除数 (x),从而将余数 (r) 定义为负整数...

x <- 2    
y <- -5
q <- x/y
k <- floor(2/-5)
kq <- floor(2/-5) * -5
r <- 2 - (floor(2/-5) * -5)
x %% y

1

语法

remainder <- dividend %% divisor

细节

文档唯一缺少的是有关被除数除数哪边的细节。 维基百科将这两个术语描述为:

被除数称为被除数,它被除以除数,结果称为商。 在此示例中,20是被除数,5是除数,4是商。

但是,与除法运算相比,模运算不返回。 相反,它返回余数

示例

为了更容易理解模运算,理想情况下被除数 > 除数

12 %% 11
# quotient is 1.090909
# remainder is 1

12 %% 10
# quotient is 1.2
# remainder is 2

12 %% 9
# quotient is 1.333333
# remainder is 3

12 %% 8
# quotient is 1.5
# remainder is 4

12 %% 7
# quotient is 1.714286
# remainder is 5

12 %% 6
# quotient is 2
# remainder is 0
# 12 is divisible by 6

12 %% 5
# quotient is 2.4
# remainder is 2

12 %% 4
# quotient is 3
# remainder is 0
# 12 is divisible by 4

12 %% 3
# quotient is 4
# remainder is 0
# 12 is divisible by 3

12 %% 2
# quotient is 6
# remainder is 0
# 12 is divisible by 2

12 %% 1
# quotient is 12
# remainder is 0
# any whole number is divisible by 1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接