2

这是我的功能

def rating(array)
  sum_count = array.values.inject(0) { |sum_count,value| sum_count + value }
  run_count = 0
  array.each do |tag,count|
    run_count += count
    cum_distn = run_count/sum_count
    logger.debug "cum_distn is #{cum_distn.to_f}; run_count is #{run_count.to_f}; sum_count is #{sum_count}"
    if cum_distn < 0.25
      ...
    elsif cum_distn < 0.5
      ...
    else
      ...
    end
  end
end

对于我的数组中每个计数为 1 的 2 个对象,我的记录器显示如下:

cum_distn is 0.0; run_count is 1.0; sum_count is 2
cum_distn is 1.0; run_count is 2.0; sum_count is 2

似乎 cum_distn 的值仅在一个循环完成后才更新,而我打算让它在 if 函数打开之前立即更新。我有两个问题:

(a) 为什么会发生这种情况(因为我看不到任何合乎逻辑的解释)?

(b) 我怎样才能纠正这个问题来做我想做的事?

4

2 回答 2

3

您正在使用整数除法,因此结果run_count / sum_count会被截断。Float要修复,只需在计算之前将其中一个转换为cum_distn. 例如:

cum_distn = run_count.to_f / sum_count
于 2011-12-22T15:56:13.190 回答
2

1)它发生是因为3/2 #=> 1但是3.0/2 # => 1.5。换句话说,integer/integer #=> integerfloat/integer #=> float

2)一开始只调用to_f一次(不是循环,因为它真的没有性能):

def rating(hash)
  sum_count = hash.values.inject(:+).to_f
  hash.inject(0) do |run_count, (tag, count)|
    run_count += count
    cum_dist = run_count/sum_count
    logger.debug "cum_distn is #{cum_distn}; run_count is #{run_count}; sum_count is #{sum_count}"
    ...
    run_count # return run_count
  end
end
于 2011-12-22T16:03:08.920 回答