简单划分的结果变化与负红利

时间:2013-06-26 23:40:13

标签: ruby division negative-number

m开始计算分钟(h)和小时数(s)的工作时间s为正;

s = 14200
h = s/3600 #=> 3
m = (s % 3600 ) / 60 #=> 56

但是,如果s为负数,我会得到不同的结果:

s = -14200
h = s/3600 #=> -4
m = (s % 3600 ) / 60 #=> 3

我不明白为什么当我以相同的秒数开始时,我得到-4小时3分钟,只是负数。

这里发生了什么?是否有任何方法可以获得积极和消极价值的一致结果?除了使用s.abs % 3600并在s为负数时修改结果?

3 个答案:

答案 0 :(得分:2)

你可以想到像这样实现的ruby中的整数除法 -

给定ab,ruby会找到q b + m = a的整数解,以便

  1. mb
  2. 的标志相同
  3. m的值尽可能小(接近于零)。
  4. 这两条规则为qa / b)和ma % b)提供了独特的解决方案。

    在您的第一个案例中,a为14200,b为3600.符合这些规则的q b + m = a的唯一解决方案为q = 3m = 1600 - - 试试吧。

    > 3 * 3600 + 1600
    # => 12400
    

    这是唯一的解决方案吗?那么q = 4呢?然后

    4 * 3600 + m = 12400
    m = -2000
    

    nope ... m现在不仅比以前更大,但它甚至是错误的符号(还记得第一条规则吗?)

    q = 2怎么样?

    2 * 3600 + m = 12400
    m = 5200
    

    nope ...我们对m的第一个解决方案较小。因此,qm的唯一值可能是3和1600。

    现在让我们试试你的第二个案例 - a -12400b又是3600。唯一解决方案是q = -4b = 2000

    我们来看看。

    > -4 * 3600 + 2000
    # => -12400
    

    它有效!

    让我们快速查看q的其他值 - 让我们尝试-3,如果我们与第一个例子进行比较,那就是“显而易见”的答案:

    -3 * 3600 + m = -12400
    m = -1600
    
    好吧......好吧,m这里比以前“更小”......所以它符合规则#2。但规则#1表示m必须与b符号相同...因此我们不接受m的否定值。

    因此,唯一独特的解决方案是q = -4m = 2000

    你问题中的其他两个部门应该从这里清楚。

    为了获得您期望的结果,您应该使用-3600代替3600来获得小时红利。

答案 1 :(得分:1)

要注意%和负数。他们很狡猾:


irb(main):011:0> 14200 % 3600
=> 3400
irb(main):012:0> -14200 % 3600
=> 200

答案 2 :(得分:1)

14200除以3600约为3.9,其在整数运算中被截断为3。

-14200除以3600约为-3.9,其在整数运算中被截断为-4。

使用%时,负数从第二个值“向后计数” - 当您记住这一点时,您的结果就会非常有意义。例如:

 1 % 6 # => 1
-1 % 6 # => 5

更新:我认为如果秒数为负数,您需要仔细考虑您想要的内容。你可能会这样做:

dir = "from now"

if s < 0
  dir = "ago"
  s = -s
end

h = s / 3600
m = (s % 3600 ) / 60

puts "s represents #{h} hours and #{m} minutes #{dir}"

做什么确实取决于hm在代码的更大背景下的含义,以及在此背景下确切的负s值的含义。

在另一种情况下,您可能希望hm具有相同的绝对值,就像s为正,但与s具有相同的符号:

sign = s < 0 ? -1 : 1
s = s.abs

h = s / 3600 * sign
m = (s % 3600 ) / 60 * sign

由您自行决定适合您情况的内容。