我可以实施四舍五入吗?

Can I implement round half to even?

我需要在花车上做 round half to even,即

  1. 如果该值是两个整数的中间值(打破平局,y 的小数部分正好是 0.5)四舍五入到最接近的偶数,
  2. 否则,标准舍入(舍入到 Ruby 中最接近的整数)。

这些是一些结果,例如:

0.5=>0
1.49=>1
1.5=>2
2.5=>2
2.51=>3
3.5=>4

我会重新打开 Float class 来创建一个 round_half_to_even 函数:

class Float
  def round_half_to_even(precision)
    if self % 1 == 0.5
      floor = self.to_i.to_f
      return floor % 2 == 0 ? floor : floor + 1
    else
      return self.round(precision)
    end
  end
end
def round_half_to_even f
  q, r = f.divmod(2.0)
  q * 2 +
  case
  when r <= 0.5 then 0
  when r >= 1.5 then 2
  else 1
  end
end

round_half_to_even(0.5) # => 0
round_half_to_even(1.49) # => 1
round_half_to_even(1.5) # => 2
round_half_to_even(2.5) # => 2
round_half_to_even(2.51) # => 3
round_half_to_even(3.5) # => 4

BigDecimal class 已经实现了 half to even 的舍入模式。您只需使用 BigDecimal.mode 方法将 ROUND_MODE 设置为 :half_even

require 'bigdecimal'

def round_half_to_even(float)
  BigDecimal.mode(BigDecimal::ROUND_MODE, :half_even)
  BigDecimal.new(float, 0).round
end

或者通过使用 round 和一些参数:

require 'bigdecimal'

def round_half_to_even(float)
  BigDecimal.new(float, 0).round(0, :half_even).to_i
end

请注意,BigDecimal#round returns 不带参数时为 Integer,带参数时为 BigDecimal。因此需要在第二个示例中调用 to_i 而不是在第一个示例中。

您可以执行以下操作:

def round_half_to_even(f)
  floor = f.to_i
  return f.round unless f==floor+0.5
  floor.odd? ? f.ceil : floor
end

round_half_to_even(2.4) #=> 2
round_half_to_even(2.6) #=> 3
round_half_to_even(3.6) #=> 4
round_half_to_even(2.5) #=> 2
round_half_to_even(3.5) #=> 4