CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Problem with Floating Point

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Max
Guest







Problem with Floating Point
PostPosted: Sat Jan 11, 2003 7:55 am     Reply with quote

<font face="Courier New" size=-1>I use a function for generate the temperature from uV.
float TcK(float Eu)
{
float Tk;
unsigned int i;
Tk=0;
if (Eu <= 0)
{
for(i=0;i<=8;i++)
Tk=Tk+(T0[i]* pow(Eu,i));
return Tk;
}
If I use :
for (t=0;t<10000;t+=500)
{
printf("\%f \%f\r",t,TcK(t));
printf("\%4.2f \%4.2f\r",t,TcK(t));

the output of t is wrong. For example for t=5000 the display show 4999.999857. Why I have this type of conversion?
With this number my routine doesn't work good.
Thank Max ___________________________
This message was ported from CCS's old forum
Original Post ID: 10612
TSchultz



Joined: 08 Sep 2003
Posts: 66
Location: Toronto, Canada

View user's profile Send private message

RE: Problem with Floating Point
PostPosted: Sat Jan 11, 2003 8:57 am     Reply with quote

This is a common problem with floating point and is not unique to the PIC or this compiler.

The floating point number is single precision and is comprised of 4 bytes. The CCS compiler uses the PIC format for a float, which differs slightly from the IEEE format but alows for an easier test of zero values. The float format used by the compiler can be found on page 168 in the manual and if you take a look at it you will see that there is a finite resolution (1 bit in 23) which is then multiplied by your exponent.

-Troy

:=<font face="Courier New" size=-1>I use a function for generate the temperature from uV.
:=float TcK(float Eu)
:={
:= float Tk;
:= unsigned int i;
:= Tk=0;
:= if (Eu <= 0)
:= {
:= for(i=0;i<=8;i++)
:= Tk=Tk+(T0[i]* pow(Eu,i));
:= return Tk;
:= }
:=If I use :
:=for (t=0;t<10000;t+=500)
:= {
:= printf("\%f \%f\r",t,TcK(t));
:= printf("\%4.2f \%4.2f\r",t,TcK(t));
:=
:=the output of t is wrong. For example for t=5000 the display show 4999.999857. Why I have this type of conversion?
:=With this number my routine doesn't work good.
:=Thank Max ___________________________
This message was ported from CCS's old forum
Original Post ID: 10613
nilsener
Guest







Re: Problem with Floating Point
PostPosted: Sat Jan 11, 2003 9:02 am     Reply with quote

Dear,

I think you can not change anything that the result of ten additions of 500.0 is 4999.999857. It depends on the accuracy of floats, I guess it is 23 Bit, a PIC can not calculate floats as accurate like you but very much faster. However, what do you see on your display is the real result of the calculation and not a type conversion of the printf function.

If you want to see 5000 on your display try something like this:

printf("\%4.0f \%4.2f\r",(t+0.5),TcK(t));

Have a look to floor(value) and ceil(value), you can use it for an exacter round algorithm. (Needs math.h)

regards nilsener


:=<font face="Courier New" size=-1>I use a function for generate the temperature from uV.
:=float TcK(float Eu)
:={
:= float Tk;
:= unsigned int i;
:= Tk=0;
:= if (Eu <= 0)
:= {
:= for(i=0;i<=8;i++)
:= Tk=Tk+(T0[i]* pow(Eu,i));
:= return Tk;
:= }
:=If I use :
:=for (t=0;t<10000;t+=500)
:= {
:= printf("\%f \%f\r",t,TcK(t));
:= printf("\%4.2f \%4.2f\r",t,TcK(t));
:=
:=the output of t is wrong. For example for t=5000 the display show 4999.999857. Why I have this type of conversion?
:=With this number my routine doesn't work good.
:=Thank Max ___________________________
This message was ported from CCS's old forum
Original Post ID: 10614
john cutler



Joined: 06 Sep 2003
Posts: 82
Location: Hot Tub, California

View user's profile Send private message

Re: Problem with Floating Point
PostPosted: Sat Jan 11, 2003 9:54 am     Reply with quote

I posted a few days ago - no one responded - different float problem - MPLAB6 displays float incorrectly in watch windows, but the actual value of the floats is ok. If I cast the float variable to an int16, it displays ok in the watch window. Anyone have any ideas?


:=<font face="Courier New" size=-1>I use a function for generate the temperature from uV.
:=float TcK(float Eu)
:={
:= float Tk;
:= unsigned int i;
:= Tk=0;
:= if (Eu <= 0)
:= {
:= for(i=0;i<=8;i++)
:= Tk=Tk+(T0[i]* pow(Eu,i));
:= return Tk;
:= }
:=If I use :
:=for (t=0;t<10000;t+=500)
:= {
:= printf("\%f \%f\r",t,TcK(t));
:= printf("\%4.2f \%4.2f\r",t,TcK(t));
:=
:=the output of t is wrong. For example for t=5000 the display show 4999.999857. Why I have this type of conversion?
:=With this number my routine doesn't work good.
:=Thank Max ___________________________
This message was ported from CCS's old forum
Original Post ID: 10615
Sherpa Doug
Guest







Re: Problem with Floating Point
PostPosted: Mon Jan 13, 2003 8:48 am     Reply with quote

:=the output of t is wrong. For example for t=5000 the display show 4999.999857. Why I have this type of conversion?
:=With this number my routine doesn't work good.
:=Thank Max</font>

This is a classic problem with floating point. It is pretty much independant of the chip or the compiler. You just need to round off to the precision you require as Nilsener mentions.

This is one reason I avoid floats if at all possible. Note that banking software NEVER uses floats. Interest rates are not calculated using exponentials. It is all done with lookup tables and +-*/. Money is too valuable to have little bits of it lost or created in the computers!

___________________________
This message was ported from CCS's old forum
Original Post ID: 10649
R.J.Hamlett
Guest







Re: Problem with Floating Point
PostPosted: Mon Jan 13, 2003 11:52 am     Reply with quote

:=:=the output of t is wrong. For example for t=5000 the display show 4999.999857. Why I have this type of conversion?
:=:=With this number my routine doesn't work good.
:=:=Thank Max</font>
:=
:=This is a classic problem with floating point. It is pretty much independant of the chip or the compiler. You just need to round off to the precision you require as Nilsener mentions.
:=
:=This is one reason I avoid floats if at all possible. Note that banking software NEVER uses floats. Interest rates are not calculated using exponentials. It is all done with lookup tables and +-*/. Money is too valuable to have little bits of it lost or created in the computers!
:=
Which is also another reason why a lot of people here have in the past recommended 'scaled integer' types to solve this sort of problem. If (for instance), you need to have accurate arithmetic for numbers with a maximum value of about one million, you could use a 32bit signed integer, and 'scale' the result, and all incoming values by a factor of 1000. This then allows a 'precision' to .001, and arithmetic without rounding errors, up to +/-2.1 million. Many languages offer this type of arithmetic (for instance Visual Basic, has a 'currency' data type handled exactly this way, for this very reason. It is also worth realising that this type of arithmetic is quicker than floating point.

Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 10654
rtrescott
Guest







floating point problem
PostPosted: Wed Aug 10, 2005 12:45 am     Reply with quote

The printf result output is indeed in error, and it IS compiler dependant. The format of a PIC float is different than IEEE, but it can be translated properly, and without the loss of precision in the displayed output. Microchip has no problem displaying the proper number in the MPLAB watch window, so it must be compiler specific. I have other compilers that use 32 bit floats and there are no output errors. As I recall, the ANSI IEEE spec describes the function of one particular bit that solves the rounding error problem.

CCS engineers need to go back into their code and repair the libraries that work with floating point conversions and resulting outputs.
sseidman



Joined: 14 Mar 2005
Posts: 159

View user's profile Send private message

Re: floating point problem
PostPosted: Wed Aug 10, 2005 6:53 am     Reply with quote

rtrescott wrote:
The printf result output is indeed in error, and it IS compiler dependant. The format of a PIC float is different than IEEE, but it can be translated properly, and without the loss of precision in the displayed output. Microchip has no problem displaying the proper number in the MPLAB watch window, so it must be compiler specific. I have other compilers that use 32 bit floats and there are no output errors. As I recall, the ANSI IEEE spec describes the function of one particular bit that solves the rounding error problem.

CCS engineers need to go back into their code and repair the libraries that work with floating point conversions and resulting outputs.


Hard to say exactly without delving in to the CCS floating point representation, but it is completely impossible to represent every floating point number exactly. The ANSI IEEE spec can't deal with this. That said, "standard" floats can represent positive and negative integers exactly, to some very high number. I don't know about the Microchip 32 bit float format that CCS uses, though. Hi-tech uses IEEE754 format. Since the compilers use different float formats differences should not be surprising.

I recommend http://www.validlab.com/goldberg/paper.ps for a pretty good discussion. http://www.mathworks.com/company/newsletter/pdf/Fall96Cleve.pdf
describes how these problems pop up in matlab, which uses double precision floats by default.

Bottom line, when dealing with floats, care is needed. A fine policy is never to do direct equality testing on floats, unless you know what you're doing. When displaying a float, filter your data through some rounding function and display with appropriate precision. Also, use integers when to do so is more appropriate (as it seems to be for "t" in the example posted)
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

The difference has two sources
PostPosted: Wed Aug 10, 2005 2:39 pm     Reply with quote

I'll use the word difference since there is no error in a mathematical sense.

The first source of any difference occurs whether it is a base 10 float or any other base since float means you pick a certain precision window ( a certain number of significant digits). If you can't fit your number into the precision then of course some of the digits in your number are lost ( tuncated)

The second source of any difference is changing between number bases.
0.1 or 1/10 in decimal can be expressed exactly but the same value 1/10 in decimal cannot be expressed in binary exactly no matter how many bits you care to go to. It's mathematics and no different for 1/3 or .33333.... can't be expressed in decimal notation exactly either.
1/3 in base 3 is exact.

For CCS the float mantissa is 23 bits binary so precision is guaranteed to be lost after 23 bits but even 0.1 decimal cannot be accurate in 23 bits binary whereas 0.5 decimal can ( the 0.1 issue is a result of the base change from 10 to 2).

Some wonder why a calcuator gets it right.
A hand held calculator does its arithmetic work in binary coded decimal so it never has the base conversion issue from the get go but it still can't get 1 div 3 right since it has to stop after a certain number of significant digits.
It's all just mathematics and we have to get used to it.
Now the work around is to take advantage of the fact that all integers can be expressed exactly in any base ( two three ten it doesn't matter) but that means you have to keep track of the decimal pt.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group