【问题标题】:Why is modulus different in different programming languages?为什么不同编程语言中的模数不同?
【发布时间】:2009-01-16 13:31:27
【问题描述】:

Perl

print 2 % -18;

-->

-16

Tcl

puts [expr {2 % -18}]

-->

-16

但是 VBScript

wscript.echo 2 mod -18

-->

2

为什么不一样?

【问题讨论】:

  • 感谢分享。我现在已经在 Python、Ruby、Javascript 和 bash 中进行了测试。 JS 和 bash 都说 2,另一个说 -16。
  • 取模运算主要属于Counting numbers,在此之外任意定义。

标签: perl vbscript tcl modulo


【解决方案1】:

wikipedia answer 在这里很有帮助。

一个简短的总结是任何整数都可以定义为

a = qn + r

所有这些字母都是整数,并且

0

几乎每种编程语言都要求 (a/n) * n + (a%n) = a。所以模数的定义几乎总是取决于整数除法的定义。整数除以负数有两种选择:2/-18 = 0 或 2/-18 = -1。根据您的语言的正确性,通常会更改 % 运算符。

这是因为 2 = (-1) * -18 + (-16) 和 2 = 0 * -18 + 2。

对于 Perl,情况很复杂。 The manual page 说:“请注意,当使用整数在范围内时,“%”使您可以直接访问由 C 编译器实现的模数运算符。该运算符对于负操作数的定义不是很好,但它会执行得更快。 " 因此,如果使用整数在范围内,它可以为 Perl(如 C)选择任一选项。如果使用整数不在范围内,则手册说“如果 $b 为负数,则 $a % $b 是 $a 减去不小于 $a 的 $b 的最小倍数(即结果将小于或等于零)。”

【讨论】:

  • 重新“可以做任何事情”,不。如果 use integer 在范围内,它只能做 C 做的事情,并且 C 标准明确要求 (a/n) + (a%n) = a 但允许选择整数除法。
  • (100/2)+(100%2) != 100 ...我错过了什么吗?
  • @B T,哎呀,错过了 n 的因素,感谢现场,我会修复它
【解决方案2】:

维基百科的"Modulo operation" 页面很好地解释了这一点。我不会尝试在这里做得更好,因为我可能会犯一个微妙但重要的错误。

问题在于你可以用不同的方式定义“余数”或“模数”,而且不同的语言选择了不同的选项来实现。

【讨论】:

  • 我认为您的原始答案直击人心。有时 '%' 表示“余数”,有时表示“模数”,它们不是一回事。
  • @Bill:我不确定是否要删除它,但归根结底是“余数”和“模数”的定义,也是(显然)不是随心所欲。
【解决方案3】:

将一个数和一个除数相除(其中一个为负数)后,您至少有两种方法可以将它们分成商和余数,例如商 * 除数 + 余数 = 数:您可以将商四舍五入负无穷大,或趋近于零。

许多语言只需选择一种。

我忍不住指出Common Lisp 提供了两者。

【讨论】:

    【解决方案4】:

    python 当然会明确通知你

    >>> divmod(2,-18)
    (-1, -16)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      • 2015-12-23
      • 2010-09-07
      • 1970-01-01
      • 2011-04-01
      相关资源
      最近更新 更多