user4479510
user4479510

Reputation:

sprintf formats not as expected

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

Answers (3)

Mark Thomas
Mark Thomas

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

7stud
7stud

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

imbuedHope
imbuedHope

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

Related Questions