# Yet another rounding issue

Discussion in 'Ruby' started by Manu Sankala, Feb 21, 2010.

1. ### Manu SankalaGuest

At school I was taught that five is always rounded up. Later on I've
been told that sometimes five is rounded to closest even number. Neither
of these seem to be the case with ruby:

irb(main):044:0> RUBY_VERSION
=> "1.8.7"
irb(main):045:0> (217.5).round
=> 218
irb(main):046:0> (218.5).round
=> 219
irb(main):047:0> (2.175*100).round
=> 217
irb(main):048:0> (2.185*100).round
=> 219
irb(main):049:0> sprintf('%.2f',2.175)
=> "2.17"
irb(main):050:0> (2.175*100.0).round/100.0
=> 2.17

Can someone please tell me how do I round 2.175 to 2.18, besides
((2.175*100).to_s+'9').to_f.round/100.0 ?
-
Manu S
--
Posted via http://www.ruby-forum.com/.

Manu Sankala, Feb 21, 2010

2. ### Jean-Julien FleckGuest

Hello,

> Can someone please tell me how do I round 2.175 to 2.18, besides
> ((2.175*100).to_s+'9').to_f.round/100.0 ?

I guess bigdecimal should be the answer

>> (2.175*100).round

=3D> 217
>> require 'bigdecimal'

=3D> true
>> a =3D BigDecimal("2.175")

=3D> #<BigDecimal:1014bd230,'0.2175E1',8(8)>
>> (a*100).round.to_s

=3D> "0.218E3"

Cheers,

--=20
JJ Fleck
PCSI1 Lyc=E9e Kl=E9ber

Jean-Julien Fleck, Feb 21, 2010

3. ### Mohit SindhwaniGuest

On 22/2/2010 1:39 AM, Manu Sankala wrote:
> At school I was taught that five is always rounded up. Later on I've
> been told that sometimes five is rounded to closest even number. Neither
> of these seem to be the case with ruby:
>
> irb(main):044:0> RUBY_VERSION
> => "1.8.7"
> irb(main):045:0> (217.5).round
> => 218
> irb(main):046:0> (218.5).round
> => 219
> irb(main):047:0> (2.175*100).round
> => 217
> irb(main):048:0> (2.185*100).round
> => 219
> irb(main):049:0> sprintf('%.2f',2.175)
> => "2.17"
> irb(main):050:0> (2.175*100.0).round/100.0
> => 2.17
>
> Can someone please tell me how do I round 2.175 to 2.18, besides
> ((2.175*100).to_s+'9').to_f.round/100.0 ?
>

Actually, this is because of the way floating point variables are
handled in a computer.

You could try:
a = 2.175
b = a + 0.0005
c = ((b * 100).round) / 100.0

irb(main):010:0> a = 2.175
=> 2.175
irb(main):011:0> b = a + 0.0005
=> 2.1755
irb(main):012:0> c = (b * 100).round / 100.0
=> 2.18
irb(main):013:0> a = 2.185
=> 2.185
irb(main):014:0> b = a + 0.0005
=> 2.1855
irb(main):015:0> c = (b * 100).round / 100.0
=> 2.19

Cheers,
Mohit.
22/2/2010 | 1:46 AM.

Mohit Sindhwani, Feb 21, 2010
4. ### Manu SankalaGuest

Mohit Sindhwani wrote:
> You could try:
> a = 2.175
> b = a + 0.0005
> c = ((b * 100).round) / 100.0

Well this is basically same as my
((some_float_here*100).to_s+'9').to_f.round/100.0
except that in my version I don't need to know how many decimals the
float originally has. "b = a + 0.0005" would fail if 'a' has mode than 3
decimals.

Since
((float_here*100).to_s+'9').to_f.round/100.0
and
(BigDecimal(float_here.to_s)*100).round.to_s.to_f/100
seem to be about as fast I think I'll go with bigfloat as it seems less
like a hack.