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

How to take only 3 digits after float for calculation?

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



Joined: 27 May 2007
Posts: 106

View user's profile Send private message

How to take only 3 digits after float for calculation?
PostPosted: Sun Apr 13, 2008 1:38 pm     Reply with quote

Say for eg. you have a value stored in a float variable.

Say I stored

float number = 2.456;

But it will stored

float number = 2.4562134654789; random bunch of numbers after the assigned valaue.
Now say I just want to use 2.456 from this above value for calculation, how do you do that?

I know you can do by multiplying by 1000 then converting to int....and so on..

But isn't there any other easy way?

Thanks in advance
Ttelmah
Guest







PostPosted: Sun Apr 13, 2008 2:54 pm     Reply with quote

Basically, no.
The float doesn't actually store 2.456. It stores a scaled binary representation of the value, and separately the scaling applied. Unfortunately, there is then no direct route from this value to a decimal 'number of digits'. You can as you say, multiply by 1000, and store as an integer. However remember that you should add 0.0004999 to the value (for +ve numbers) to get normal 4/5 rounding, or you will be always trimming 'downwards'.
Remember that you can use the %w printf formatter to output such scaled values directly, with the decimal point inserted, and that it is much faster if you can work with such values for the arithmetic itself.
For FP values there is normally not any reason to throw away accuracy. If you are going to do this, it should be the last thing done, or you increase the errors as arithmetic proceeds. For output, you always have the field width specifier, so the 'extra' characters need not be seen.

Best Wishes
Izzy



Joined: 27 May 2007
Posts: 106

View user's profile Send private message

PostPosted: Sun Apr 13, 2008 3:00 pm     Reply with quote

One more question:

When you print to a serial LCD, is there a way you can reserve space for ...say for eg 2.3 precision float? meaning 2 digit and 3 precision ...like 35.123

say if the print should start after 5th block on the 20 x 4 LCD.

_ _ _ _ _ 3 5 . 1 2 3

now I dont want the number to print

_ _ _ _ _ 2 . 2 2 3 if the number is 1 digit with 3 precision

I am trying to get something like

_ _ _ _ _ _ 2 . 2 2 3 ...Notice that the 6th block is empty, so that the decimal remains aligned.


Is it possible?


I tried using "%3.2f" but it only displays 2 digit with 3 precision , it does not leave the block empty if I am trying to print 1 float 3 precision float.


Does anyone knows about this?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 13, 2008 4:26 pm     Reply with quote

Do a test with an if() statement. If the number is less than 10.000
then print a space first. Then display the number.
Izzy



Joined: 27 May 2007
Posts: 106

View user's profile Send private message

PostPosted: Sun Apr 13, 2008 4:36 pm     Reply with quote

Thanks for the reply.

If there were only couple of values to be displayed, I would have done that.

But I have almost 30 - 40 values to be displayed, so I am not sure if it would be appropiate. I will see.
Ttelmah
Guest







PostPosted: Mon Apr 14, 2008 2:59 am     Reply with quote

%3.2, shouldn't give '3 precision'. The number after the decimal, is the number of digits wanted after the decimal point (should be '3' for you), while the number in front, is the _total_ field width (must also include the decimal point, and the digits after the decimal). Normally, the specifier you would want, would be % 6.3f. Note the 'space'. However (unfortunately), CCS does not support this... :-(
However the number of things you have to output, doesn't mean you can't use a test. Also, you only seem to be talking about possible numbers up to 99.999 max (since this is the space you are allowing).
Generate your own output routine, like
Code:

void right_just_val(float val) {
   if (val >=10.) printf(lcd_putc"%6.3f",val);
   else printf(lcd_putc" %5.3f",val);
}

This will handle positive numbers from 0.000 to 99.999. Simply position your write cursor on the LCD, where you want the number to print, and call this with the number (I am assuming you are using lcd_putc - otherwise substitute your own output function).

Best Wishes
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Mon Apr 14, 2008 12:01 pm     Reply with quote

Ttelmah is right in mentioning that there is nothing untoward occurring with
Quote:


float number = 2.456;

But it will stored

float number = 2.4562134654789; random bunch of numbers after the assigned valaue.

Perhaps the expectation of accuracy stems from a misconception as to what a number really is. We have inherited a notation over the last few thousand years. It has the form "2.456" using base ten and the 0...9 symbols. The PIC has registers that perform operations. If a binary notation of a number is transfered to a register then the PIC can manipulate it without translation. When "2.456" is typed while coding or read in through a port the ascii chars have to be translated. Float is stored as notation in the PIC data space and is manipulated via floating pt routines based on the base two ( binary) system. Moving between base ten to base two and back introduces notational differences. This is to be expected the value 1/3 can't be expressed fully in 1.nnnnn base ten notation and thats before base translation occurs. Handheld calculators avoid many of these issues by doing calculations in BCD and mimicking the long hand calculations we do with our inherited base ten notation.
Numbers calculated this way are often accepted as accurate and are used to question the accuracy of results from a binary based system. There is no real answer either we adopt binary notation or we design PIC like calculators. The calculator approach is not very efficient neither is changing to binary notation from decimal. That leaves us with the differences the two notations will from time to time introduce.
Morcilla



Joined: 08 Apr 2008
Posts: 2

View user's profile Send private message

Recomend
PostPosted: Thu May 22, 2008 7:58 am     Reply with quote

i recomend to use:

Code:

   sprintf(var,"%2.1f",pctrl->temp_set);
   my_prints(1,1,var);



where my_prints function is

Code:

void my_prints(unsigned char x ,unsigned char y ,char* s){
   unsigned int len;
   lcd_gotoxy(x,y);
   len = strlen(s);
   for(i=0;i<len;i++)
      lcd_putc(s[i]);
}


this is more cheaper for the PIC than

Code:


printf(lcd_putc"%2.1f",pctrl->temp_set);






Regards.
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