我在这里运行一些代码。我尝试了-40 % 3
。它给出的输出是2
。当我在C中执行相同的操作时,我得到:
int i = (-40) % 3
printf("%d", i);
输出结果为
-1
两种语言在执行模运算时内部是如何运作的?
维基百科说:
给定两个正数,
a
(被除数)和n
(除数),a模n(记为a mod n)是欧几里得除法的余数。
... 当a
或n
为负数时,朴素定义就会失效,编程语言在如何定义这些值方面存在差异。
现在的问题是为什么Ruby中的-40 % 3
等于2
,或者换句话说,背后的数学原理是什么?
让我们从欧几里得除法开始,它规定:
给定两个整数
a
和n
,其中n ≠ 0
,存在唯一的整数q
和r
,使得a = n*q + r
且0 ≤ r < |n|
,其中|n|
表示n
的绝对值。
现在注意到商的两个定义:
q=floor(a/n)
,余数r
为:这里商(q
)始终向下舍入(即使它已经是负数),余数(r
)与除数具有相同的符号。
q = sgn(a)floor(|a| / n)
,其中sgn
是符号函数。
余数(r
)与被除数(a
)具有相同的符号。
现在一切都取决于q
:
- 如果实现遵循定义
1
,并将q
定义为floor(a/n)
,那么40 % 3
的值为1
,而-40 % 3
的值为2
。在这里,Ruby似乎是这种情况。- 如果实现遵循定义
2
,并将q
定义为sgn(a)floor(|a| / n)
,那么40 % 3
的值为1
,而-40 % 3
的值为-1
。在这里,C和Java似乎是这种情况。
(int) % (unsigned int)
,与这个问题无关。现在https://dev59.com/-XRA5IYBdhLWcg3wyBD1更适合作为重复问题。 - Mr Lister