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

发布于 2024-07-11 19:02:52 字数 339 浏览 5 评论 0原文

Perl

print 2 % -18;

-->

-16

Tcl

puts [expr {2 % -18}]

-->

-16

但是 VBScript

wscript.echo 2 mod -18

-->

2

为什么有区别?

Perl

print 2 % -18;

-->

-16

Tcl

puts [expr {2 % -18}]

-->

-16

but VBScript

wscript.echo 2 mod -18

-->

2

Why the difference?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

香草可樂 2024-07-18 19:02:52

维基百科答案在这里相当有帮助。

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

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 来说,情况很复杂。 手册页说:“请注意,当使用整数在范围内时,”% “让您可以直接访问由 C 编译器实现的模运算符。该运算符对于负操作数的定义并不明确,但执行速度会更快。”因此,如果使用整数,它可以选择 Perl 的任一选项(如 C)在适用范围。 如果使用整数不在范围内,手册上说“如果$b是负数,则$a%$b是$a减去$b的不小于$a的最小倍数(即结果将小于或等于零)。

The wikipedia answer is fairly helpful here.

A short summary is that any integer can be defined as

a = qn + r

where all of these letters are integers, and

0 <= |r| < |n|.

Almost every programming language will require that (a/n) * n + (a%n) = a. So the definition of modulus will nearly always depend on the definition of integer division. There are two choices for integer division by negative numbers 2/-18 = 0 or 2/-18 = -1. Depending on which one is true for your language will usually change the % operator.

This is because 2 = (-1) * -18 + (-16) and 2 = 0 * -18 + 2.

For Perl the situation is complicated. The manual page says: "Note that when use integer is in scope, "%" gives you direct access to the modulus operator as implemented by your C compiler. This operator is not as well defined for negative operands, but it will execute faster. " So it can choose either option for Perl (like C) if use integer is in scope. If use integer is not in scope, the manual says " If $b is negative, then $a % $b is $a minus the smallest multiple of $b that is not less than $a (i.e. the result will be less than or equal to zero). "

天煞孤星 2024-07-18 19:02:52

维基百科的“模运算”页面对此进行了很好的解释。 我不会尝试在这里做得更好,因为我可能会犯一个微妙但重要的错误。

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

Wikipedia's "Modulo operation" page explains it quite well. I won't try to do any better here, as I'm likely to make a subtle but important mistake.

The rub of it is that you can define "remainder" or "modulus" in different ways, and different languages have chosen different options to implement.

酒解孤独 2024-07-18 19:02:52

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

许多语言只选择一种。

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

After dividing a number and a divisor, one of which is negative, you have at least two ways to separate them into a quotient and a remainder, such that quotient * divisor + remainder = number: you can either round the quotient towards negative infinity, or towards zero.

Many languages just choose one.

I can't resist pointing out that Common Lisp offers both.

蓝天白云 2024-07-18 19:02:52

当然,python 明确地告诉你

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

python, of course, explicitly informs you

>>> divmod(2,-18)
(-1, -16)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文