Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Exercise Caution When Using Floating Point Numbers

I understand floating point numbers can be somewhat imprecise but I'm a bit bothered today when I see the following evaluates to false:

   1: float f = .16f;
   2: double d = .16d;
   3:  
   4: Assert.That(f, Is.EqualTo(d))

Annoyingly I wanted to see what the two values are:

   1: Console.WriteLine((double)f)
   2: Console.WriteLine(d);

produces the following respectively:

.159999996423721

.16

What bothers me about this, and I'm hoping someone can eloquently explain this, the MSDN docs say this should be implicitly converted.  From the MSDN doc article on implicit numeric conversions:

  • From float to double.

Float is 32-bit and double is 64-bit, so why can't the float fit nicely inside the address space for the double?

Hell, if you're not going to respect the integrity of the number what's the point of the implicit conversion?


Posted 11-05-2008 2:13 PM by Tim Barcz
Filed under: ,

[Advertisement]

Comments

Kelly Leahy wrote re: Exercise Caution When Using Floating Point Numbers
on 11-05-2008 4:00 PM

Tim, the problem is that 0.16 is not the "real" value of the float either.  The real value of the float is, in fact, 0.159999996423721, since IEEE floating point numbers can't exactly store 0.16 (ever).  At least, the value I get from Excel is: 0.159999996423721.

The floating point string formatting routines in .NET and other languages are "smart" and actually show this as 0.16, but in reality that is the value that's in the 32-bit IEEE number.

That said, when you convert to double, you get 29 more 'digits' of accuracy (29 more bits, actually), and so these all get filled with zeros (since there's no way for .NET to know that you meant 0.16 when you "said" 0.159999996423721.

Hopefully this helps.  If you want more details you can check Wikipedia's Single_precision and Double_precision pages.

I also have a spreadsheet that does these calculations in Excel if you're interested in seeing the details.  I can post it on my blog if there's interest.

Igor Ostrovsky wrote re: Exercise Caution When Using Floating Point Numbers
on 11-05-2008 4:31 PM

Kelly is right. The precision is not getting lost in the conversion. The problem is that 0.159999996423721 is the best possible float representation of 0.16.

Tim Barcz wrote re: Exercise Caution When Using Floating Point Numbers
on 11-05-2008 5:16 PM

Simple question then:

Why isn't double d = .16; returning the same value?

Jean-Francois Cantin wrote re: Exercise Caution When Using Floating Point Numbers
on 11-05-2008 5:50 PM

Tim, I went through this a while back and was disappointed to find that Kelly is right. If you absolutely require 0.16, the only way to get that, is to use decimal d = 0.16.

Kevin H wrote re: Exercise Caution When Using Floating Point Numbers
on 11-05-2008 6:57 PM

If you translate this to base 10, and assume that a float is 3 significant figures and double is 6, then the following would be similar:

float f = 1/32f;         // f = 1.56 * 10^-2

double d = 1/32d;  // d = 1.56250 * 10^-2

Assert.That(f, Is.Equal(d));

Sure, the float gets converted to a double, but that means the expanded float is 1.56000, which clearly isn't 1.56250, and the assertion fails.

It's always best to compare the absolute difference being smaller than a threshold than equality when talking about floats.. Even something simple like:

float f = 0;

for (int i=0; i<100; i++)

 f += 0.1f;

Assert.That(f, Is.Equal(10.0f));

would fail, but for different reasons.

Kevin H wrote re: Exercise Caution When Using Floating Point Numbers
on 11-05-2008 7:12 PM

Reflecting my comments in binary,

.16 (decimal) = .0010100011110101110000101001 (binary), exactly

This gets stored in a floating point as:

[1.]01000111101011100001010 x 2^-3

And stored in double as:

[1.]0100011110101110000101001 x 2^-3

When the float gets promoted to double, it can't know about the extra digits.

Kelly Leahy wrote re: Exercise Caution When Using Floating Point Numbers
on 11-05-2008 7:19 PM

> why isn't d = 0.16 (double) returning the same value

because double d = 0.16D also ISN'T 0.16.  Think about it this way.  If I asked you to store 1/7 in decimal in 20 digits, then write it to disk, then read it from disk, and convert it to 40 digits, would it match the result if I told you to store 1/7 in 40 digits in the first place?  The point is, by the time you 'store' 1/7 in a specified number of decimal digits, you have truncated it to something other than 1/7.  Then, when you convert it to some other number of digits, you've already lost the 'real' value so there's no way to know exactly how you're supposed to convert it.

Does this make sense?

Kelly Leahy wrote re: Exercise Caution When Using Floating Point Numbers
on 11-05-2008 7:26 PM

BTW, I forgt to mention (clearly) that

double d = 0.16

is also not 0.16.  It's 0.16 - 2.22E-16 approximately.

this means that if you were to do something like come up with a 'real' way to compute 0.16 using numbers that CAN be precisely represented in double precision numbers, and you did this math inside the floating point support for the CPU (which uses 10 byte - 80bit arithmetic internally), and then loaded your 0.16 from the 8-byte (64bit) number and subtracted it, you'd get a number that isn't zero...

In other words, if you could do something like:

x = foo(a,b,c)   where a,b,c are double (IEEE 64-bit), and x is the IEEE 80-bit FPU result, then do

y = 0.16D

z = x - y

z will not be zero, due to the fact that y = 0.16D zero extends 0.16, while x is an 80-bit representation of 0.16.

Ian Cooper wrote re: Exercise Caution When Using Floating Point Numbers
on 11-07-2008 3:40 AM

Comparing floating point numbers is one of those 'looks harder than it is' issues. The usual technique is to check that the delta between them is not greater than a certain fraction. There is a pretty good summary here:

www.cygnus-software.com/.../comparingfloats.htm

This one suprises a lot of people at first.

Code Monkey Labs wrote Weekly Web Nuggets #37
on 11-10-2008 1:08 PM

Pick of the week: Advice For Developers On Starting An Independent Software Vendor (ISV) Business General Tips For Preparing For A Technical Presentation : Scott Hanselman shares how he prepares for technical presentations. LINQ Cheat Sheet : Brad Vincent

devlicio.us wrote re: Exercise Caution When Using Floating Point Numbers
on 04-05-2011 8:53 PM

Exercise caution when using floating point numbers.. Nice :)

devlicio.us wrote re: Exercise Caution When Using Floating Point Numbers
on 04-22-2011 9:40 AM

Exercise caution when using floating point numbers.. OMG! :)

devlicio.us wrote re: Exercise Caution When Using Floating Point Numbers
on 05-01-2011 3:18 AM

Exercise caution when using floating point numbers.. Ho-o-o-o-t :)

devlicio.us wrote re: Exercise Caution When Using Floating Point Numbers
on 06-02-2011 8:31 PM

Exercise caution when using floating point numbers.. Dandy :)

devlicio.us wrote re: Exercise Caution When Using Floating Point Numbers
on 06-03-2011 1:28 AM

Exercise caution when using floating point numbers.. He-he-he :)

devlicio.us wrote re: Exercise Caution When Using Floating Point Numbers
on 06-04-2011 8:51 PM

Exercise caution when using floating point numbers.. Retweeted it :)

devlicio.us wrote re: Exercise Caution When Using Floating Point Numbers
on 06-05-2011 1:46 AM

Exercise caution when using floating point numbers.. Nice :)

devlicio.us wrote re: Exercise Caution When Using Floating Point Numbers
on 06-14-2011 6:10 AM

Exercise caution when using floating point numbers.. Smashing :)

mh76 pon videos z8yf wrote re: Exercise Caution When Using Floating Point Numbers
on 07-02-2011 2:35 AM

Exercise caution when using floating point numbers.. Ho-o-o-o-t :)

4x24 porn u407 wrote re: Exercise Caution When Using Floating Point Numbers
on 07-02-2011 7:33 AM

Exercise caution when using floating point numbers.. Reposted it :)

4oxy porno yw1k wrote re: Exercise Caution When Using Floating Point Numbers
on 07-02-2011 7:31 PM

Exercise caution when using floating point numbers.. Slap-up :)

top bookmarking sites wrote re: Exercise Caution When Using Floating Point Numbers
on 01-18-2013 11:43 PM

dQ7urN Muchos Gracias for your blog. Want more.

pills for lose weight wrote re: Exercise Caution When Using Floating Point Numbers
on 02-01-2013 2:26 PM

22ZMkA Thanks a lot for the blog article.Really thank you! Much obliged.

buy discount viagra wrote re: Exercise Caution When Using Floating Point Numbers
on 02-02-2013 8:15 PM

Kvhsxq I value the blog post.Really thank you! Cool.

buy clomid no prescription wrote re: Exercise Caution When Using Floating Point Numbers
on 03-01-2013 1:05 AM

hyY7nr I value the blog.Really looking forward to read more. Keep writing.

social bookmarks wrote re: Exercise Caution When Using Floating Point Numbers
on 03-14-2013 8:46 AM

vIy1RY Thanks so much for the article post.Really thank you! Great.

social bookmarking service wrote re: Exercise Caution When Using Floating Point Numbers
on 03-22-2013 10:17 PM

qh9165 Thanks for sharing, this is a fantastic post.Really looking forward to read more. Keep writing.

buy social bookmarks wrote re: Exercise Caution When Using Floating Point Numbers
on 04-03-2013 5:07 AM

FxfEYg I appreciate you sharing this blog post.Much thanks again. Fantastic.

good social bookmarks wrote re: Exercise Caution When Using Floating Point Numbers
on 06-21-2013 12:40 AM

n0wNxn Great, thanks for sharing this blog.Thanks Again. Really Great.

best news wrote re: Exercise Caution When Using Floating Point Numbers
on 08-03-2013 9:39 PM

GyFv5l Thanks again for the blog article.Thanks Again. Much obliged.

make money online wrote re: Exercise Caution When Using Floating Point Numbers
on 09-12-2013 7:33 PM

I64kLF Very informative post.Really thank you! Awesome.

check out these guys! wrote re: Exercise Caution When Using Floating Point Numbers
on 10-16-2013 1:33 AM

nLc8Ot Thank you for your article.Much thanks again. Really Great.

link building wrote re: Exercise Caution When Using Floating Point Numbers
on 10-23-2013 6:37 PM

1DQVp0 Really enjoyed this post. Much obliged.

top seo guys wrote re: Exercise Caution When Using Floating Point Numbers
on 10-31-2013 9:56 PM

vpgwpg Thanks-a-mundo for the article.Really looking forward to read more. Really Great.

awesome things! wrote re: Exercise Caution When Using Floating Point Numbers
on 01-19-2014 5:53 PM

ZPXyFK Wow, great blog post.Much thanks again. Cool.

seo for cheap wrote re: Exercise Caution When Using Floating Point Numbers
on 03-25-2014 3:47 PM

loFpwg Fantastic post.Really thank you! Great.

stunning service wrote re: Exercise Caution When Using Floating Point Numbers
on 04-05-2014 9:00 PM

fxXRQi I am so grateful for your article.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)