【问题标题】:Negative number division in Ruby [duplicate]Ruby中的负数除法[重复]
【发布时间】:2025-12-26 05:20:08
【问题描述】:

谁能解释下面的负数除法结果:

2.6.1 :001 > -25/24
 => -2 
2.6.1 :002 > 25/24
 => 1 

为什么是-2 而不是-1

更多关于奇怪行为的例子:

2.6.1 :003 > 24/25
 => 0 
2.6.1 :004 > -24/25
 => -1 

有什么想法吗? 谢谢。

【问题讨论】:

  • 因为(-1 - 1/24)的楼层等于-2
  • 这是否意味着在整数除法的情况下Ruby总是在后台调用#floor?而(-1 - 1/24) 是从哪里来的?
  • 以下是行为背后的更详细解释:*.com/a/19518866/1954610
  • @TomLord 哇,所以有一些类似的历史讨论,非常感谢!在使用 Ruby 10 年后,直到今天我才问过自己这个问题 :)。

标签: ruby


【解决方案1】:

不同的编程语言对(负)整数除法使用不同的定义。 Ruby 使用KnuthConcrete Mathematics 中描述的那个,p. 82.

可以通过一个例子来说明:假设我们正在处理几周。我们的星期从星期日开始。数字是从零开始的,所以我们从第 0 周开始,第 0 天开始:

----- 0 -----
0 1 2 3 4 5 6
S M T W T F S
^

如果我们将向前移动 9 天,我们将在周 1,日 2

----- 0 -----   ----- 1 -----
0 1 2 3 4 5 6   0 1 2 3 4 5 6
S M T W T F S   S M T W T F S
                    ^

这些值由/% 返回:

9 / 7 #=> 1
9 % 7 #=> 2

如果我们将向后移动 9 天(从 0 开始),我们在周 -2,日 5

---- -2 -----   ---- -1 -----   ----- 0 -----
0 1 2 3 4 5 6   0 1 2 3 4 5 6   0 1 2 3 4 5 6
S M T W T F S   S M T W T F S   S M T W T F S
          ^

使用/%

-9 / 7 #=> -2
-9 % 7 #=> 5

在该页的边缘有一个有趣的注释:

小心使用其他定义的计算机语言。

【讨论】:

  • 感谢您如此详细的解释。顺便说一句,SO Knuth 资源的链接已损坏。
  • @belgoros 它是为了指向*,修复它:-)
  • 这是具体的解释,谢谢!
【解决方案2】:

您可以考虑整数除法的一种方法是:

  1. 您进行浮点除法。
  2. 您将结果向下取整。

因此:

(25.0 / 24.0).floor  # => 1
(-25.0 / 24.0).floor # => -2

【讨论】:

    【解决方案3】:

    我可以通过使用括号简单地找到所需的功能,

    -(25/24)
    # => -1
    

    也许,为什么 -25/24 让你感到惊讶:

    对于浮点除法中的实际值,请提供-1.041

    您使用整数除法的结果正在向下舍入到更负的值 -2。这也称为楼层划分

    【讨论】:

    • Pheu,这个只是增加了另一个问题:-25/24 => -2,但是(-25/24) => -1
    • @belgoros,好问题,我在 python 文档中找到了答案。请检查已编辑的答案。
    • 谢谢。所以我的建议是在每个部门结束时调用#floor 是正确的吗?我在 Ruby 文档中没有找到任何答案。
    • @belgoros,是的,这都是关于从地板到负面的:)
    • @belgoros,这都是关于优先级的,所以-(25.0/24.0).floor就像-((25.0/24.0).floor) #--> -(1)
    【解决方案4】:

    Ruby 中的整数除法返回地板或除法的浮点结果:

    https://ruby-doc.org/core-2.6/Numeric.html#method-i-div

    使用/ 执行除法,然后将结果转换为整数。数字没有定义/ 运算符;这是留给子类的。

    相当于num.divmod(numeric)[0]

    divmod 使用floor: :

    q = floor(x/y)
    x = q*y + r
    

    【讨论】:

    • 我没有问过#divmod的方法,而是#/
    • 查看更新。
    • 目前还不清楚(恕我直言)所有对#/ 方法的调用都将使用#floor