0

I am trying to add an int to a float. My code is:

int main() {
   char paus[2];
   int millit = 5085840;
   float dmillit = .000005;
   float dbuffer;

   printf("(float)milit + dmillit: %f\n",(float)millit + dmillit);
   dbuffer = (float)millit + dmillit;
   printf("dbuffer: %f\n",dbuffer);

   fgets(paus,2,stdin);
   return 0;
 }

The output looks like:

(float)millit + dmillit: 5085840.000005
dbuffer: 5085840.000000

Why is there a difference? I've also noticed that if I change dmillit = .5, then both outputs are the same (5085840.5), which is what I would expect. Why is this? Thanks!

Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
Jade
  • 57
  • 8
  • possible duplicate of http://stackoverflow.com/questions/1907114/integers-and-float-precision – Jens Gustedt Aug 27 '10 at 19:58
  • float is only half the precision of double and even double can be less precise than the "Floating Point" registers. If you are doing "Floating Point" calculations it is generally preferred to use double rather than float (unless you have some weird space requirements). – Martin York Aug 27 '10 at 21:53
  • To point out the (somewhat) obvious, `float` only has about 7 digits of precision. Your integer already soaks all of that up, so there isn't any left over to express the six places after the decimal point. Looked at another way, `dbuffer` got exactly the result you told it too, with all the precision you allowed it to have. – RBerteig Aug 28 '10 at 08:13

4 Answers4

7

(float)millit + dmillit evaluates to a double value. When you print the value, it displays correctly, but when you store it in a float variable, the precision is lost.

Philippe Leybaert
  • 168,566
  • 31
  • 210
  • 223
4

the precision that you are trying to use is too big for a float. On the printf function it is being casted into a double to be printed.

See the page IEEE 754 float calculator to better understand this.

korbes
  • 1,273
  • 1
  • 12
  • 18
  • 4
    There's no "probably" about it. You can't pass a `float` to a variadic function like `printf()`. It is automatically promoted to `double`. – David Thornley Aug 27 '10 at 19:27
  • Ah, ok that makes sense. And thanks for the link, I found that site once before but couldn't remember where, and have since been looking. Thanks! – Jade Aug 27 '10 at 19:34
  • Thanks @David. Wasn't sure if it was certainly like that. Edited the answer. – korbes Aug 27 '10 at 20:30
1

I believe the floating point addition in the printf statement may be silently casting the result to a double, so it has more precision.

Mark Wilkins
  • 40,729
  • 5
  • 57
  • 110
  • 2
    Glancing at the C99 draft standard, it's OK for an implementation to evaluate `float` addition as type `double`, and it of course has to be passed as a `double`. – David Thornley Aug 27 '10 at 19:30
1
 printf("(float)milit + dmillit: %f\n",(float)millit + dmillit); 

I believe that here, the addition is done as a double, and passed as a double to printf.

 dbuffer = (float)millit + dmillit;    
 printf("dbuffer: %f\n",dbuffer);  

Here's the addition is done as a double, then reduced to a float to be stored in dbuffer, then expanded back to a double to be passed to printf.

James Curran
  • 101,701
  • 37
  • 181
  • 258