|
I have recently noticed a large influx of questions concerning the following topic.
Dear Larry,
When calculating a floating point value, why does my calculation show an incorrect answer?
Steve L.
Hello Steve,
To answer this question let me start off with the basics. A majority of floating point numbers are approximations. Dynamic C currently supports only single precision floating point. We do not follow the IEEE 754 standard exactly but are pretty close to it. The deviations we have made are designed to speed up processing and usually result in only one LSB difference. The format of a floating point number is 1 bit sign, 8 bit exponent and 23 bit mantissa.
The exponent is in offset 2’s complement notation and represents a power of 2. The decimal value of the most significant bit of the mantissa is 0.25 (2-2), the next bit is 0.125 (2-3), etc. There is a “hidden” bit, of value 0.5 (2-1), which is always set. The range of decimal values, which can be represented, is approximately +/-1.0E+/-38.
The following program illustrates a typical error when using floating point values:
main (){ float fpval; int intval; float roundVal; fpval = .90/10.0; if ( fpval == 0.09 ) printf ( "Calculated value is correct! \n\r" ); else printf ( "Calculated value is wrong??? \n\r" ); printf ( " 7.5f = %7.5f \n\r", fpval ); printf ( "11.9f = %11.9f \n\n\r", fpval ); fpval *= 10.0; intval = (int)fpval; printf ( "converted to integer = %d \n\r", intval ); if ( fpval >= 0.0 ) roundVal = 0.5; else roundVal = -0.5; intval = (int)(fpval + roundVal); printf ( "converted to integer after adjustment = %d \n\r", intval ); }
Here are the results of running the program:
Calculated value is wrong???
7.5f = 0.09000
11.9f = 0.089999996
Converted to integer = 0
Converted to integer after adjustment = 1
The program above sheds light on three things to look out for. First, be aware that a Single Precision Floating Point has 6-7 decimal digits of resolution. Attempting to use more than 6-7 decimal digits of resolution may lead you astray. This is not specific to Dynamic C but is true for any compiler. Second, never use a test for equality for any calculated floating point value, regardless of the compiler. Third, be wary of converting to integers that round to the value closer to 0.
Larry C.
Larry Cicchinelli is Rabbit Semiconductor’s Technical Support Manager. He has 30 years of embedded experience, and is considered one of the foremost authorities on Rabbit products. Larry and his staff offer comprehensive technical support to Rabbit customers.
Submit your questions for Larry via email at
AskLarry@rabbit.com
|