Reputation:
I've got a problem with rounding using sprintf
. I get passed '%0.0f'
as the format. sprintf
rounds not as expected: 0.5
should be rounded to 1
, instead it rounds to 0
, which is against the general rounding rule, whereas 1.5
, 2.5
etc. is being rounded correctly:
sprintf('%0.0f', 0.5)
=> "0"
sprintf('%0.0f', 1.5)
=> "2"
Why is this so and how can I achieve my expected behaviour?
Upvotes: 2
Views: 280
Reputation: 37517
sprintf
performs banker's rounding, which rounds 0.5 to the nearest even number. This method is often used by statisticians, as it doesn't artificially inflate averages like half-up rounding.
The Float#round
method (in Ruby 2.4+) accepts a parameter which can be one of:
half: :up
(the default)half: :down
half: :even
(banker's rounding)Apparently you are expecting round
's default, so you can just do a .round
to your number before printing.
Upvotes: 3
Reputation: 48619
how can I achieve my expected behaviour?
Round the float before you give it to sprintf:
2.4.0 :001 > sprintf('%0.0f', 0.5.round)
=> "1"
2.4.0 :002 > sprintf('%0.0f', 1.5.round)
=> "2"
Upvotes: 2
Reputation: 563
This is expected behavior for printf
. The default rounding mode is to round to the nearest valid value, and in case of a tie to pick the even number. Since 0.5
is treated as being in exactly the middle of 0
and 1
, it tends to 0
because it is the even number.
Upvotes: 0