问题
I need to do round half to even on floats, i.e.,
- if the value is half-way between two integers (tie-breaking, fraction part of y is exactly 0.5) round to the nearest even integer,
- else, standard round (which is Round to nearest Integer in Ruby).
These are some results, for example:
0.5=>0
1.49=>1
1.5=>2
2.5=>2
2.51=>3
3.5=>4
回答1:
I would reopen the Float class to create a round_half_to_even function :
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
回答2:
The BigDecimal
class has the rounding mode half to even already implemented. You just have to set the ROUND_MODE
to :half_even
with BigDecimal.mode method:
require 'bigdecimal'
def round_half_to_even(float)
BigDecimal.mode(BigDecimal::ROUND_MODE, :half_even)
BigDecimal.new(float, 0).round
end
Or by using the round with some arguments:
require 'bigdecimal'
def round_half_to_even(float)
BigDecimal.new(float, 0).round(0, :half_even).to_i
end
Please note that BigDecimal#round
returns an Integer
when used without arguments, but a BigDecimal
when used with arguments. Therefore the need to call to_i
in the second example but not in the first.
回答3:
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
回答4:
You could do the following:
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
来源:https://stackoverflow.com/questions/35359699/can-i-implement-round-half-to-even