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 CCS Technical Support

Floating point rounding in CCS

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







Floating point rounding in CCS
PostPosted: Sun Mar 23, 2003 1:14 pm     Reply with quote

How can I round floating point
numbers with certain numbers of
digits? For instance I need
a function like this:

float a,b;

a=20.54332;
b=round2(a);
( b=20.54)

I tried this but it seems it does not work:

int c;
float a,b;

a=20.54332;
c=a*100;
b=floor(c/100);
___________________________
This message was ported from CCS's old forum
Original Post ID: 12976
Steve H.
Guest







Re: Floating point rounding in CCS
PostPosted: Sun Mar 23, 2003 2:19 pm     Reply with quote

:=
:=I tried this but it seems it does not work:
:=
:= int c;
:= float a,b;
:=
:= a=20.54332;
:= c=a*100;
:= b=floor(c/100);

In the code above you took a float and multiplied it by an integer 100 and stuffed the result in an integer. That won't work at all on this C or the most expensive C+++++++ compiler.

If you are rounding for display just printf the required digits. If you are trying to round for accuracy in your program good luck - with the limited significant digits of the floats the very next operation will probably 'un-round' your result anyway.

Steve H.
___________________________
This message was ported from CCS's old forum
Original Post ID: 12978
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

Re: Floating point rounding in CCS
PostPosted: Sun Mar 23, 2003 3:24 pm     Reply with quote

CCS floating point numbers have a 23 bit mantissa. Any base 10 number that can be expressed as a power series of 2
a*2^22+b*2^21........2^0 where a,b,c .... have values of 0 or1 can be accurately represented. This includes all the whole numbers up to 2^23-1 but would not include 0.1 since it can't be expressed exactly. Note .5 or 1/2 is ok since all we have to do is subtract one from the exponent and see it as the whole number 1 ( base 2).
It is more to do with how numbers are represented in base 2 arithmetic verus the decimal system. For example 0.1 in decimal is expressable but in base 2 it doesn't neatly fit so an approximation is made. Simmilarly 1/3 can't be expressed exactly in the decimal system so we use .333333333333..... and stop at some point with an approximation. However 1/3 in base 3 arithmetic is a neat fit of 0.1. Some numbers such as pi have to be approximated no matter which base you use. A pocket calculator uses BCD so it never leaves base10 as did the early IBM computers. Binary is efficient but not all decimal numbers can be an exact fit.
___________________________
This message was ported from CCS's old forum
Original Post ID: 12981
R.J.Hamlett
Guest







Re: Floating point rounding in CCS
PostPosted: Sun Mar 23, 2003 4:16 pm     Reply with quote

:=
:=:=
:=:=I tried this but it seems it does not work:
:=:=
:=:= int c;
:=:= float a,b;
:=:=
:=:= a=20.54332;
:=:= c=a*100;
:=:= b=floor(c/100);
:=
:=In the code above you took a float and multiplied it by an integer 100 and stuffed the result in an integer. That won't work at all on this C or the most expensive C+++++++ compiler.
:=
Actually it will. In this case though the limit of the int at 255, will cause problems...

:=If you are rounding for display just printf the required digits. If you are trying to round for accuracy in your program good luck - with the limited significant digits of the floats the very next operation will probably 'un-round' your result anyway.
:=

The key is that the only way to give accurate results, is to shift away from the use of floats. You can give the sort of effect required like this:

void main() {
char store[8];
int ctr;
int flag;
float a;
a=20.54332;
flag=false;
sprintf(store,"\%05ld",(short int)((a*100)+0.005));
for (ctr=0;ctr<3;ctr++) {
if (store[ctr]!='0' || flag) {
putchar(store[ctr]);
flag=true;
}
else putchar(' ');
}
printf(".\%2s",&store[3]);
while (true) ;
}

If rounding is for accuracy, rather than just for the output, then the solution is to switch to using a scaled integer.

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







Re: Floating point rounding in CCS
PostPosted: Sun Mar 23, 2003 4:39 pm     Reply with quote

:=:=
:=:=:=
:=:=:=I tried this but it seems it does not work:
:=:=:=
:=:=:= int c;
:=:=:= float a,b;
:=:=:=
:=:=:= a=20.54332;
:=:=:= c=a*100;
:=:=:= b=floor(c/100);
:=:=
:=:=In the code above you took a float and multiplied it by an integer 100 and stuffed the result in an integer. That won't work at all on this C or the most expensive C+++++++ compiler.
:=:=
:=Actually it will. In this case though the limit of the int at 255, will cause problems...
:=
:=:=If you are rounding for display just printf the required digits. If you are trying to round for accuracy in your program good luck - with the limited significant digits of the floats the very next operation will probably 'un-round' your result anyway.
:=:=
:=
:=The key is that the only way to give accurate results, is to shift away from the use of floats. You can give the sort of effect required like this:
:=
:=void main() {
:= char store[8];
:= int ctr;
:= int flag;
:= float a;
:= a=20.54332;
:= flag=false;
:= sprintf(store,"\%05ld",(short int)((a*100)+0.005));
:= for (ctr=0;ctr<3;ctr++) {
:= if (store[ctr]!='0' || flag) {
:= putchar(store[ctr]);
:= flag=true;
:= }
:= else putchar(' ');
:= }
:= printf(".\%2s",&store[3]);
:= while (true) ;
:=}
:=
:=If rounding is for accuracy, rather than just for the output, then the solution is to switch to using a scaled integer.
:=
:=Best Wishes
Change the 'short int' to int16 in the above. I forgot to reset this after checking the code worked in a normal C...

Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 12985
Steve H.
Guest







Oops! Thanks....
PostPosted: Sun Mar 23, 2003 11:56 pm     Reply with quote

>>Actually it will. In this case though the limit of the int
>> 255, will cause problems...

Oops, my bad! You are right, K&R says that floats are converted to ints in standard C.

Thanks for correcting this for me....

:-)

In CCS - I have noticed that explicit casting must be done and that in the 2.6x version that I use the compiler won't cast correctly unless explicitly told to.

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







Re: Oops! Thanks....
PostPosted: Mon Mar 24, 2003 3:11 am     Reply with quote

:=>>Actually it will. In this case though the limit of the int
:=>> 255, will cause problems...
:=
:=Oops, my bad! You are right, K&R says that floats are converted to ints in standard C.
:=
:=Thanks for correcting this for me....
:=
:=:-)
:=
:=In CCS - I have noticed that explicit casting must be done and that in the 2.6x version that I use the compiler won't cast correctly unless explicitly told to.
:=
It is variable. Some things will convert OK, but if you look through the past posts, you will find a lot of advice (including posts from me), saying that manual casting avoids a lot of problems in CCS C. Basically if you are doing mixed type maths, it is better to not rely on the implicit casts. As you say, the results and effects do vary from version to version.
It has the (slight) advantage, of making you think about what maths type is involved in a particular operation, but is one of the biggest 'fundamental' differences between the CCS C, and a normal compiler...

Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 12993
Steve H
Guest







Right....
PostPosted: Mon Mar 24, 2003 1:49 pm     Reply with quote

Right, I've had problems with intermediate overflow when doing something like this,

int a;
long b,c;

c = a * b; // Can / will overflow when doing the multiply

c = (long)a * b; // Works fine!

So I cast everything with CCS now!
___________________________
This message was ported from CCS's old forum
Original Post ID: 13017
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