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
Author Message
SBK
Guest

 Floating point rounding in CCS Posted: Sun Mar 23, 2003 1:14 pm 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 Posted: Sun Mar 23, 2003 2:19 pm := :=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

 Re: Floating point rounding in CCS Posted: Sun Mar 23, 2003 3:24 pm 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 Posted: Sun Mar 23, 2003 4:16 pm := :=:= :=:=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 Posted: Sun Mar 23, 2003 4:39 pm :=:= :=:=:= :=:=:=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.... Posted: Sun Mar 23, 2003 11:56 pm >>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.... Posted: Mon Mar 24, 2003 3:11 am :=>>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.... Posted: Mon Mar 24, 2003 1:49 pm 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: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First
 All times are GMT - 6 Hours Page 1 of 1

 Jump to: Select a forum Software----------------General CCS C DiscussionCode LibraryEZ App Lynx Hardware----------------CCS ICD / Mach X / Load-n-Go
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