# Bug Rounding Floats? (9.245 \* 100).round =\> 924? S/B 925!

**URL:** <https://www.ruby-forum.com/t/bug-rounding-floats-9-245-100-round-924-s-b-925/172520>\
**Category:** Ruby\
**Created:** [July 22, 2009, 7:01pm UTC](https://www.ruby-forum.com/t/bug-rounding-floats-9-245-100-round-924-s-b-925/172520 "2009-07-22T19:01:09Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ddoherty03](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/9de053/32.png) [@ddoherty03](https://www.ruby-forum.com/u/ddoherty03)\
**Post date:** [July 22, 2009, 7:01pm UTC](https://www.ruby-forum.com/t/bug-rounding-floats-9-245-100-round-924-s-b-925/172520/1 "2009-07-22T19:01:09Z")

</div>

All,

Would someone try the below unit test and explain why ruby does not  
pass. It came up while I was trying to write a generalized rounding  
method for floats that takes the number of place to round to as a  
parameter. It gave wrong answers, but only on rare inputs.

For example, (9.245 \* 100).round should be 925, but my ruby gives 924.

=================================  
#! /usr/bin/env ruby

# 

require ‘test/unit’

class TestFloatRounding \< Test::Unit::TestCase  
def test\_round  
assert\_equal(925, 924.5.round, “Rounding Error: 924.5.round”)  
assert\_equal(9.25, (9.245 \* 10.0**2).round / 10.0**2, “Rounding  
Error: (9.245 \* 10.0**2).round / 10.0**2”)  
assert\_equal(925, (9.245 \* 10.0\*\*2).round, "Rounding Error:(9.245

- 10.0**2).round")  
assert\_equal(924.5, 9.245 \* 10.0**2, “Rounding Error: 9.245 \*  
10.0\*\*2”)  
assert\_equal(925, 924.5.round, “Rounding Error: 924.5.round”)  
assert\_equal(924.5, 9.245 \* 10 \* 10, “Rounding Error: 9.245 \* 10 \*  
10”)  
assert\_equal(925, (9.245 \* 10 \* 10).round, "Rounding Error: (9.245
- 10 \* 10).round")  
assert\_equal(925.0, 9.245 \* 10 \* 10 + 0.5, "Rounding Error: 9.245
- 10 \* 10 + 0.5")  
assert\_equal(925, (9.245 \* 10 \* 10 + 0.5).floor, “Rounding Error:  
(9.245 \* 10 \* 10 + 0.5).floor”)  
end  
end  
===================================

---

<div class="post-metadata">

**Author:** ![ddoherty03](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/9de053/32.png) [@ddoherty03](https://www.ruby-forum.com/u/ddoherty03)\
**Post date:** [July 22, 2009, 7:47pm UTC](https://www.ruby-forum.com/t/bug-rounding-floats-9-245-100-round-924-s-b-925/172520/2 "2009-07-22T19:47:25Z")

</div>

2009/7/22 ddoherty03 [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> For example, (9.245 \* 100).round should be 925, but my ruby gives 924.

try what your term really is:

printf(“%.50f”,9.245 \* 100)

-Thomas

–  
Thomas P.  
removed\_email\_address@domain.invalid

> **[Google Sites: Sign-in](https://accounts.google.com/v3/signin/identifier?dsh=S620820767%3A1688215231590083&continue=https%3A%2F%2Fsites.google.com%2Fsite%2Fsites%2Fsystem%2Ferrors%2FWebspaceNotFound%3Fpath%3D%2Fthopre%2F&followup=https%3A%2F%2Fsites.google.com%2Fsite%2Fsites%2Fsystem%2Ferrors%2FWebspaceNotFound%3Fpath%3D%2Fthopre%2F&ifkv=AeDOFXh02uKbsw3nSUf-NfdDRL7c8mhihJ98xR335pzJARsfTSfaNyUnrpOeEMc7eCk5NmeMRTuhFw&passive=1209600&service=jotspot&flowName=WebLiteSignIn&flowEntry=ServiceLogin)**
>
> Access Google Sites with a personal Google account or Google Workspace account (for business use).

> **[thopre](https://thopre.wordpress.com/)**
>
> Entwicklungen für die Bühne des Lebens

## Mike Ditka [http://www.brainyquote.com/quotes/authors/m/mike\_ditka.html](http://www.brainyquote.com/quotes/authors/m/mike_ditka.html)

“If God had wanted man to play soccer, he wouldn’t have given us arms.”

---

<div class="post-metadata">

**Author:** ![ddoherty03](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/9de053/32.png) [@ddoherty03](https://www.ruby-forum.com/u/ddoherty03)\
**Post date:** [July 22, 2009, 8:10pm UTC](https://www.ruby-forum.com/t/bug-rounding-floats-9-245-100-round-924-s-b-925/172520/3 "2009-07-22T20:10:48Z")

</div>

At 2009-07-22 01:37PM, “Thomas P.” wrote:

> printf("%.50f",9.245 \* 100)  
> Welcome to IEEE floating-point arithmetic. Any programming language  
> that uses it will be subject to the same results.

---

<div class="post-metadata">

**Author:** ![ddoherty03](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/9de053/32.png) [@ddoherty03](https://www.ruby-forum.com/u/ddoherty03)\
**Post date:** [July 22, 2009, 9:26pm UTC](https://www.ruby-forum.com/t/bug-rounding-floats-9-245-100-round-924-s-b-925/172520/4 "2009-07-22T21:26:11Z")

</div>

On Jul 22, 1:13 pm, Glenn J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> A workaround, convert the expression to a string and back to a number:
> 
> ```
> num = Float("%.1f" % (9.245 * 100)).round
> 
> puts "yippee" if num == 925
> 
> ```

Glenn,

Thanks for the explanation. If I could pick your brain for a second  
on how to generalize your workaround, I would greatly appreciate it.

Here is how I tried to implement the “nround” method.

######################################  
class Float  
def nround(n = 0)  
(self \* 10.0 \*\* n).round / 10.0 \*\* n  
end  
end  
######################################

My issue is getting the workaround to deal with the parameter n  
properly.

Regards,

---

<div class="post-metadata">

**Author:** ![ddoherty03](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/9de053/32.png) [@ddoherty03](https://www.ruby-forum.com/u/ddoherty03)\
**Post date:** [July 22, 2009, 8:19pm UTC](https://www.ruby-forum.com/t/bug-rounding-floats-9-245-100-round-924-s-b-925/172520/5 "2009-07-22T20:19:34Z")

</div>

At 2009-07-22 02:08PM, “Glenn J.” wrote:

> > printf("%.50f",9.245 \* 100)
> 
> Welcome to IEEE floating-point arithmetic. Any programming language  
> that uses it will be subject to the same results.

A workaround, convert the expression to a string and back to a number:

```
num = Float("%.1f" % (9.245 * 100)).round

puts "yippee" if num == 925
```

---

<div class="post-metadata">

**Author:** ![ddoherty03](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/9de053/32.png) [@ddoherty03](https://www.ruby-forum.com/u/ddoherty03)\
**Post date:** [July 23, 2009, 4:41pm UTC](https://www.ruby-forum.com/t/bug-rounding-floats-9-245-100-round-924-s-b-925/172520/6 "2009-07-23T16:41:13Z")

</div>

At 2009-07-22 03:22PM, “ddoherty03” wrote:

> Here is how I tried to implement the “nround” method.  
> properly.  
> Taking Bil K.'s advice,

```
require 'bigdecimal'
require 'bigdecimal/util'

class Float
  def nround(n=0)
    (self.to_d * (10.0**n).to_d).round.to_f / 10.0**n
  end
end

p 9.245.nround(2) # => 9.25
```

---

<div class="post-metadata">

**Author:** ![ddoherty03](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/9de053/32.png) [@ddoherty03](https://www.ruby-forum.com/u/ddoherty03)\
**Post date:** [July 23, 2009, 10:41am UTC](https://www.ruby-forum.com/t/bug-rounding-floats-9-245-100-round-924-s-b-925/172520/7 "2009-07-23T10:41:01Z")

</div>

ddoherty03 wrote:

> Thanks for the explanation. If I could pick your brain for a second  
> on how to generalize your workaround, I would greatly appreciate it.

If performance isn’t a problem, you could use ‘bigdecimal’:

[http://ruby-doc.org/stdlib/libdoc/bigdecimal/rdoc/](http://ruby-doc.org/stdlib/libdoc/bigdecimal/rdoc/)

See for example,

[Ruby Quiz - NDiff (#46)](http://rubyquiz.com/quiz46.html)

Regards,

---

<div class="post-metadata">

**Author:** ![ddoherty03](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/9de053/32.png) [@ddoherty03](https://www.ruby-forum.com/u/ddoherty03)\
**Post date:** [July 23, 2009, 5:00pm UTC](https://www.ruby-forum.com/t/bug-rounding-floats-9-245-100-round-924-s-b-925/172520/8 "2009-07-23T17:00:30Z")

</div>

On Jul 23, 9:37 am, Glenn J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > end  
> > class Float  
> > def nround(n=0)  
> > (self.to\_d \* (10.0**n).to\_d).round.to\_f / 10.0**n  
> > end  
> > end
> 
> ```
> p 9.245.nround(2) # => 9.25
> 
> ```
> 
> –  
> Glenn J.  
> Write a wise saying and your name will live forever. – Anonymous

Bil & Glenn & Thomas,

Thanks. Performance is not a problem, so this works for me.

Much appreciated.
