为什么不同编程语言的模数不同?

时间:2009-01-16 13:31:28

标签: perl vbscript tcl modulo

的Perl

print 2 % -18;

- >

-16

的Tcl

puts [expr {2 % -18}]

- >

-16

但是VBScript

wscript.echo 2 mod -18

- >

2

为什么会有差异?

4 个答案:

答案 0 :(得分:30)

wikipedia answer在这里非常有帮助。

简短摘要是任何整数都可以定义为

a = qn + r

其中所有这些字母都是整数,

0< = | r | < | N |。

几乎每种编程语言都需要(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减去$ b的最小倍数不小于$ a(即结果将小于或等于零)。“

答案 1 :(得分:9)

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

它的缺点是你可以用不同的方式定义“余数”或“模数”,不同的语言选择了不同的选项来实现。

答案 2 :(得分:4)

在除数和除数之后,其中一个是负数,你至少有两种方法可以将它们分成商和余数,这样商数*除数+余数=数:你可以将商数四舍五入负无穷大,或朝零。

许多语言只选择一种。

我无法抗拒地指出Common Lisp提供了两者。

答案 3 :(得分:2)

当然,

python明确通知你

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