Hello, I am a first time poster and not that familiar with HTML codes or uses. I did try to look this one up and could not find it.

When I enter 26.2, it gives me 26.20001. I do not understand where that 1 is coming from.

Thank you

#include <stdio.h>
#define MAXCOUNT 4

int main()
{
   int count;
   float num, total;

   printf("\n This program will ask you to enter %d numbers.\n\n", MAXCOUNT);

   count=1;
   total=0.0;

   while (count<=MAXCOUNT)
   {
      printf("Enter a number: ");
      scanf("%f", &num);
      total+=num;
      printf("The total is now %f\n", total);
      count++;
   }

   printf("\n\nThe final total of the %d numbers entered is %f\n",MAXCOUNT, total);

   return 0;

}

I'm not exactly sure why that is happening with the float variable, and i am very new to C myself, but i ran the code and changed the num variable to type double and changed the scanf function to %lf and it returned correct values. hopefully this helps.

>When I enter 26.2, it gives me 26.20001. I do not understand where that 1 is coming from.
A float only has 6-digits of precision, anything else is garbage.

>i ran the code and changed the num variable to type double and changed the scanf function to %lf >and it returned correct values. hopefully this helps.

A double has 15-digits of precision, that's why it worked for you.

this is a common "problem" with floating point numbers: most floating point representations of decimal values are not exact numbers.. they are approximations.

here's the short answer:

single-precision floating point value (type float) is represented by 24 bits in the mantissa, and 8 bits in the exponent. this is in Base 2 number system. so any fractional power of 2 (or sum of such numbers) is easily represented, but numbers not a sum of fractional powers of two must be rounded at some point.

ask yourself how much precision do you need? is 4 or 5 significant digits enough for you? much of the time in general use it is, so use it and round off with he format specifiers for printf()

printf("%5.03f \n",myFloat);

will give you 26.200 printed to the screen. if you need more precision than 6 digits, use type double.

now the long answer:

think of how we (with our human base 10 counting) have "problems" with numbers like 1/3 and 1/6 and 1/12. its not a lot of fun to take 0.333333333 to infinite places, so we eventually round off at some point.

the "rules" for computing floating point numbers is covered by IEEE Std 754. here is an over-simplified example:

your number 26 is represented by 11010 as an integer... but as a float, it is represented by 11010.00000000000000000, where the "." is the "binary point". if you wanted to represent 26.5 that's easy to do in binary: it is just saying 26 and 1/2, note that the one-half is a fractional power of two. so its represented by 11010.10000000... see that the "1" to the right of the binary point is in the place of 2^-1 (1/2)

if you wanted 26.25, thats fine also: it's 11010.01000000... where the "1" to the right of the binary point is in the 2^-2 place (1/4). 26.125 is 11010.00100000... with that "1" now in the 2^-3 place (1/8)

those were just simple fractions but you can also sums of fractions, such as 26.625, without problems because 1/2 + 1/8 = 0.625, so binary is 11010.10100000 = 26.625

but what about your 26.2? 26 we know, but 0.2 is 1/5 -- not so easy for binary counting. people don't have problems with 1/5 in our 10-fingered counting system, because 1/5 is a simple sum of fractional powers of 10 (1/10 plus 1/10).

but counting 1/5 kind of sucks if you only have two fingers to count with:

fract	  power   decimal            sum

1/8     = 2^-3  = 0.125   
1/16    = 2^-4  = 0.0625             0.1825
1/128   = 2^-7  = 0.0078125          0.1953125
1/256   = 2^-8  = 0.00390625         0.19921875  		
1/2048  = 2^-11 = 0.00048828125      0.19970703125
1/4096  = 2^-12 = 0.000244140625     0.199951171865
1/32768 = 2^-15 = 0.000030517578125  0.199981689443125
1/65536 = 2^-16 = 0.0000152587890625 0.1999969482321875

so, with single precision float (23 bits plus a hidden bit in the mantissa), we've just now run out of bits to represent base-10 value of 26.2 ... in binary, it is 11010.001100110011001100 ... which is actually 26.199997...

if we had more precision as type double, the pattern "0011" would just keep repeating for a while longer until it's bits likewise ran out (youd get about 15 accurate decimal points instead of 6)

now why did it give you 26.200001, you ask? because IEEE Standard 754 allows rounding to afford more accuracy. typical implementations round "toward the nearest number". in this case, the least significant bit is set

11010.001100110011001101

adding the amount 1/262144 = 2^-18 = 0.000003814697265625 for a total of 26.200000762929453125, then taken to the floating point default of 6 decimal places: 26.200001

.

hah.. check this out.

change your line of code that prints the sum to print out 10 decimal places

printf("The total is now %.10f\n", total);

then recompile and run:

C:\Users\Owner\Desktop\rob work\scratch>float.exe

 This program will ask you to enter 4 numbers.

Enter a number: 26.2
The total is now 26.2000007629

there it is: 23 bits of precision, plus one "implied" bit, rounded to the nearest number. "up" in this case.


last thing. i probably shouldnt get into, but just for completeness:

your floating point binary value actually looks like this:

0 10000011 10100011001100110011010
|  |______|  |_____________________|                                          
|        |                          |
|        |                          |____"normalized" mantissa
|        |
|        |_____exponent = 2^4
|
|_____sign bit (positive)

look up IEEE 754 bit fields if you really want to go there.


.

Wow! I thank you guys very much. Some more for me to remember now.

dont worry, you wont remember it much of it. i didnt remember much of it, other than the basic principle that floating point numbers have finite amount of accuracy and precision.

i had to look up those details i had learned once and mostly forgotten. i was writing ^ and ^^ out as much for myself as for anyone else.

just try to understand it, and you'll at least remember where to go look it up next time. (IEEE standards)

This article has been dead for over six months. Start a new discussion instead.