从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
为负数时修改结果?
答案 0 :(得分:2)
你可以想到像这样实现的ruby中的整数除法 -
给定a
和b
,ruby会找到q b + m = a
的整数解,以便
m
与b
m
的值尽可能小(接近于零)。这两条规则为q
(a / b
)和m
(a % b
)提供了独特的解决方案。
在您的第一个案例中,a
为14200,b
为3600.符合这些规则的q b + m = a
的唯一解决方案为q = 3
和m = 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
的第一个解决方案较小。因此,q
和m
的唯一值可能是3和1600。
现在让我们试试你的第二个案例 - a
-12400
而b
又是3600
。唯一解决方案是q = -4
和b = 2000
。
我们来看看。
> -4 * 3600 + 2000
# => -12400
它有效!
让我们快速查看q
的其他值 - 让我们尝试-3,如果我们与第一个例子进行比较,那就是“显而易见”的答案:
-3 * 3600 + m = -12400
m = -1600
好吧......好吧,m
这里比以前“更小”......所以它符合规则#2。但规则#1表示m
必须与b
符号相同...因此我们不接受m
的否定值。
因此,唯一独特的解决方案是q = -4
和m = 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}"
做什么确实取决于h
和m
在代码的更大背景下的含义,以及在此背景下确切的负s
值的含义。
在另一种情况下,您可能希望h
和m
具有相同的绝对值,就像s
为正,但与s
具有相同的符号:
sign = s < 0 ? -1 : 1
s = s.abs
h = s / 3600 * sign
m = (s % 3600 ) / 60 * sign
由您自行决定适合您情况的内容。