Hi,
I had simulated the following code using C166 compiler
float idata fval; void main( void ) { char cnv_str[30]= {'\0' }; fval = 100.578; sprintf( cnv_str, "%f", fval ); printf("format_data_str = %s\n\r",cnv_str); printf("fval = %f\n\r",fval); while(1); }
I obtained the foolowing result after executing the code format_data_str = 100.578003. fval = 100.578003. The result value is different from the one that was stored in the variable. The result value should have been 100.578000 instead of 100.578003. Please let me know the possible casuse of this problem. If this is a compiler error then suggest me how to overcome this problem. Thanks in advance.
This has come up so many times it is unbelievable. First you must understand how floating point arithmetic works. Do a google search for 'floating point' and read up a bit. You can start here: www.petebecker.com/.../js200006.html
Regards, - mike
Please let me know the possible casuse of this problem.
The problem is that your expectations on how floating-point arithmetics works is different from how they actually work.
If this is a compiler error then suggest me how to overcome this problem.
It is not a compiler error/bug. The problem is insufficient knowledge of floating-point arithmetics and pitfalls on the side of the programmer.
In short: Floating oint can not store any value. It can only store some values. The "floating-point" part means that when tne number is small, a float variable can store values close together. When the value is large (the exponent) the float vairable can store huge values but the storable values will be a long way from each other.
So what happens when you want to store a value "in between" the values that are possible to store? The float variable will get a storable value that is directly above or below the value you specified.
Because of this, you can print a floating point number with many digits, but a limited number of digits will be valid. And if you do mathematical operations, the errors will accumulate meaning that you may start off with 8 correct digits and after a number of operations only have 6 or 7 correct values. When I say correct, I mean correctly rounded.
In your case, you expect a float to store 9 correct digits. 9 gits would be every integer from 0 to one billion, i.e. it would take a 30-bit unsigned integer. Your float is 32 bit large, but it need to consume one bit for the sign, and it need to consume a number of bits (8) for the exponent. So it will have 23 bits for the mantissa. 23 bits can only store a value 0 .. 8 millions, and if you try to store a value as large as a billion (relatively seen) then the "dots" that are storeable will be every 128 ticks away from each other.
Back to your number: 23 bits (2^23) means that at best, the step size between representable values will be about 1 / 8,000,000.
Your value had the size of 100, so 100 / 8,000,000 means that the step size (at best) will be about 1 / 80 000 or in decimal 0.0000125.
This was a bit simplified. In reality, the numbers are scaled so that the most significant bit of the mantissa is thrown away, to let the 23 bits of the mantissa to just store the decimal expansion. That gains a single bit extra of precision as long as the number is within the range that they can be normalized.
Try a search for "IEEE754" starting in your C166 User's Guide. It shows how floats are stored. Or play with this nice tool:
www.h-schmidt.net/.../IEEE754.html
this may help too: http://www.keil.com/support/docs/2191.htm
Thanks mike..the document has been of great help
Regards, Bhushan
Thanks the tool was of great help..
Regards, Bhushan.