繁体   English   中英

为什么对于负整数,C 和 Ruby 之间的模运算符 (%) 的行为不同?

[英]Why is the behavior of the modulo operator (%) different between C and Ruby for negative integers?

我在这里运行了一些代码。 我试过-40 % 3 它给了我输出2 当我在 C 中执行相同的操作时,我得到:

int i = (-40) % 3
printf("%d", i);

输出是

-1

两种语言如何在内部执行模运算?

维基说:

给定两个正数a (被除数)和n (除数),模 n (缩写为 mod n)是a by n的余数。
....an为负数时,幼稚的定义就会失效,并且编程语言在定义这些值的方式上有所不同


现在的问题是为什么-40 % 3在 Ruby 中是2或者换句话说,它背后的数学是什么?

让我们从欧几里得除法开始,它指出:

给定两个整数an ,其中n ≠ 0 ,存在唯一整数qr使得a = n*q + r0 ≤ r < |n| , 其中|n| 表示n的绝对值。

现在注意商的两个定义:

  1. Donald Knuth描述了地板除法,其中商由地板函数q=floor(a/n) ,余数r是:

在此处输入图片说明

这里商 ( q ) 总是向下舍入(即使它已经是负数),余数 ( r ) 与除数具有相同的符号

  1. 一些实现将商定义为:

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 的情况。

在 Java 和 C 中,模运算的结果与被除数具有相同的符号,因此 -1 是您示例中的结果。

在 Ruby 中,它与除数具有相同的符号,因此根据您的示例,结果为 +2。

在 ruby​​ 实现中,当分子为负而分母为正时,取模运算符回答的问题是,“从分子中减去时,允许分母整除的最小正数是多少?”

在所有实现中,当分子和分母都是正数时,要回答的问题是:“当从分子中减去时,允许分母平均除以结果的最小正数是多少?”

因此,您可以看到 ruby​​ 实现始终在回答相同的问题,即使结果起初并不直观。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM