36

整数除法 -1 / 5 应该返回什么?我完全被这种行为搞糊涂了。我认为在数学上它应该是 0,但是 python 和 ruby​​ 返回-1。

为什么不同的语言在这里表现不同?请有人解释。谢谢。

| Language  | Code           | Result |
|-----------+----------------+--------|
| ruby      | -1 / 5         |     -1 |
| python    | -1 / 5         |     -1 |
| c         | -1 / 5         |      0 |
| clojure   | (int (/ -1 5)) |      0 |
| emacslisp | (/ -1 5)       |      0 |
| bash      | expr -1 / 5    |      0 |
4

2 回答 2

49

简短的回答:语言设计者可以选择在进行整数除法时他们的语言是向零、负无穷还是正无穷舍入。不同的语言做出了不同的选择。

长答案: Python 和 Ruby 的语言作者都认为向负无穷舍入比向零舍入更有意义(就像 C 一样)。python 的创建者在这里写了一篇关于他的推理的博客文章。我在下面摘录了很多内容。

今天我被要求(再次)解释为什么 Python 中的整数除法会返回结果的下限,而不是像 C 那样截断为零。

对于正数,这不足为奇:

>>> 5//2
2

但如果其中一个操作数为负数,则结果为下限,即从零四舍五入(向负无穷大):

>>> -5//2
-3
>>> 5//-2
-3

这让一些人感到不安,但有一个很好的数学原因。整数除法运算 (//) 和它的兄弟,模运算 (%),一起满足一个很好的数学关系(所有变量都是整数):

a/b = q with remainder r

这样

b*q + r = a and 0 <= r < b
(assuming a and b are >= 0).

如果您希望关系扩展为负 a(保持 b 为正),您有两种选择:如果您将 q 截断为零,则 r 将变为负数,因此不变量变为 0 <= abs(r) < 否则,您可以将 q 降低到负无穷大,并且不变量保持 0 <= r < b。[更新:修复了这个段落]

在数学数论中,数学家总是更喜欢后一种选择(参见例如Wikipedia)。对于 Python,我做出了同样的选择,因为模运算有一些有趣的应用,其中 a 的符号是无趣的。考虑采用 POSIX 时间戳(自 1970 年初以来的秒数)并将其转换为一天中的时间。因为一天有 24*3600 = 86400 秒,所以这个计算只是 t % 86400。但是如果我们用负数来表示 1970 年之前的时间,“向零截断”规则将给出毫无意义的结果!使用底线规则一切正常。

于 2013-10-22T13:10:38.103 回答
5

整数除法是特定于实现的。来自维基百科的模运算

许多实现使用截断除法,其中商由截断 q = trunc( a / n ) 定义,换句话说,它是从精确有理商到 0 方向的第一个整数,余数为r = a - n q . 非正式地讲,商“向零舍入”,因此余数与被除数具有相同的符号。

Knuth描述了下限除法,其中商由下限函数 q =floor( a / n ) 定义,余数r

r = a - nq = a - n \left\lfloor {a \over n} \right\rfloor。

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

于 2013-10-22T13:27:08.277 回答