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

break float number to get separate numbers.
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
hayee



Joined: 05 Sep 2007
Posts: 252

View user's profile Send private message

break float number to get separate numbers.
PostPosted: Thu Jun 17, 2010 7:25 am     Reply with quote

Hi,
I have a floating number, suppose 55.96, and I want to store each digit in an integer variable like value1=5, value2=5, value3=9, value4=6.
Can someone tell me how I can break the floating number to get separate numbers.
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Thu Jun 17, 2010 7:30 am     Reply with quote

Code:
int8 huns, tens, ones, tenths, hundredths;
float number;

huns = (int8) (number / 100);
tens = (int8) ((number / 10) % 10);
ones = (int8) ((number % 100) % 10);


...etc etc etc
hayee



Joined: 05 Sep 2007
Posts: 252

View user's profile Send private message

PostPosted: Thu Jun 17, 2010 7:40 am     Reply with quote

What about the values after point (9 and 6).
How do I get them?
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Thu Jun 17, 2010 8:37 am     Reply with quote

Multiply by 10 and extract the "one", which is actually the tenth. Repeat to extract the hundredth.
hayee



Joined: 05 Sep 2007
Posts: 252

View user's profile Send private message

PostPosted: Thu Jun 17, 2010 11:43 pm     Reply with quote

I am getting error on this line
Code:

tens=(int8)((total_rs/10)%10);


Error is : only integers are supported for this operation.

I have declared tens as an int8 and total_rs as an float.
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Fri Jun 18, 2010 7:10 am     Reply with quote

Do the cast to an int first.

Code:
int16 int_total_rs;
int8 tens;
float total_rs;

int_total_rs = (int16) total_rs;
tens = (int8)((int_total_rs/10)%10);
Ttelmah



Joined: 11 Mar 2010
Posts: 19510

View user's profile Send private message

PostPosted: Fri Jun 18, 2010 8:38 am     Reply with quote

To optimise a little, it is perhaps worth using some of the other functions.
1) Integer arithmetic is far more efficient than 'float'. Typically it takes about 4* the machine cycles to do a float division, compared to an int16.
2) If you start with the number *100, then divide by ten, you get two terms in one operation, if you use the 'div' operator, rather than /.
So:
Code:

ldiv_t lidivval;
int8 digits[4];
float starting_val;

ldivval=ldiv((signed int16)(starting_val*100),10);
digits[3]=ldivval.rem;
ldivval=ldiv(ldivval.quot,10);
digits[2]=ldivval.rem;
ldivval=ldiv(ldivval.quot,10);
digits[1]=ldivval.rem;
digits[0]=ldivval.quot;

By no means the best possible, but a lot better than the float solution.
The most significant digit is in digits[0].

Best Wishes
hayee



Joined: 05 Sep 2007
Posts: 252

View user's profile Send private message

PostPosted: Sat Jun 19, 2010 1:56 am     Reply with quote

I have made the following changes
Code:

int16 int_total_rs;


 int_total_rs = (int16) total_rs;
 hunds =(int8) (total_rs/100);
 tens  =(int8) ((int_total_rs/10)%10);
 ones  =(int8) ((int_total_rs % 10)) ;
 tenth =(int8) (((int_total_rs*10)%100)%10);
 hundredth=(int8) (((int_total_rs*100)%100)%10);

code is compiling without any error.
But i am not getting the values of tenth and hundredth,all other values i am getting (hunds,tens,ones).
Ttelmah



Joined: 11 Mar 2010
Posts: 19510

View user's profile Send private message

PostPosted: Sat Jun 19, 2010 3:05 am     Reply with quote

Of course you are not....
What type of number can an integer hold?.
Why do you think I multiply the float value by 100, before using it as an integer in my version?.

Worth understanding that '%', performs a division, and gives the remainder. '/' performs a division. The ldiv operator, performs a single divsion, and gives you the result, _and_ the remainder in one operation. Half the time.
As posted, you perform 8 integer divsions, and two multiplications. About 3300 machine cycles. Using lfiv, reduces this to about 1/3rd the cycles...
The equivalent using your target names, is:

Code:

ldiv_t ldivval;
float starting_val;

ldivval=ldiv((signed int16)(starting_val*100),10);
hundredth=ldivval.rem;
ldivval=ldiv(ldivval.quot,10);
tenth=ldivval.rem;
ldivval=ldiv(ldivval.quot,10);
ones=ldivval.rem;
ldivval=ldiv(ldivval.quot,10);
tens=ldivval.rem;
hunds=ldivval.quot;


Be aware at this point, of the limitations of signed and unsigned 16bit integers on 'size'. This version will fail if the value is above 327.67, while the version using unsigned intgers and not using ldiv, will fail above 655.35. You need to consider how youare going to handle the situation when numbers are above the limits.


Best Wishes
hayee



Joined: 05 Sep 2007
Posts: 252

View user's profile Send private message

PostPosted: Sat Jun 19, 2010 5:49 am     Reply with quote

Thanks Ttelmah for your option.
Kindly guide me about the working of the given code so that i understand it and implement it easily.

Also will i require to include any driver file for that code.
Ttelmah



Joined: 11 Mar 2010
Posts: 19510

View user's profile Send private message

PostPosted: Sat Jun 19, 2010 7:40 am     Reply with quote

'Driver', no. Read the compiler manual...
The 'point' is that ldiv, is a supplied function (you have to include stdlib.h, but the manual tells you this), which returns both the quotient, and remainder from an integer division.

So you start with a float number. Say 145.6723.
Then you multiply this by ten, and convert this to an integer, so you have now got '14567'. You have 'lost' the 23 (this is what was happening to your code, but without the multiplication, you would lose the '.6723'.
Divide this by ten, and you now have 1456, with the _remainder_ 7. The bottom digit wanted.
Do it again. 145, remainder 6.
and again.
14, remainder 5.
and again.
1, remainder 4.
The '1' left as the quotient after the last division is the top digit.

So you get the digits in reverse order.

Best Wishes
hayee



Joined: 05 Sep 2007
Posts: 252

View user's profile Send private message

PostPosted: Sat Jun 19, 2010 7:58 am     Reply with quote

Hm,that's exactly what i want.
I have included the stdlib.h
but it is giving alot of errors

first error : ldiv_t ldivval;//what should i declear here.

i am using " total_rs " instead of " starting_val "

2nd error : " .rem"
3rd error : " quot "

how to resolve these errors.
Ttelmah



Joined: 11 Mar 2010
Posts: 19510

View user's profile Send private message

PostPosted: Sat Jun 19, 2010 8:30 am     Reply with quote

Code:

#include <18F2321.h>
#fuses HS,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=10000000)

#include <stdlib.h>

int8 hundredth,tenth,ones,tens,hunds;

void main(void){
    ldiv_t ldivval;
    float total_rsl=234.21;

    ldivval=ldiv((signed int16)(total_rs*100),10);
    hundredth=ldivval.rem;
    ldivval=ldiv(ldivval.quot,10);
    tenth=ldivval.rem;
    ldivval=ldiv(ldivval.quot,10);
    ones=ldivval.rem;
    ldivval=ldiv(ldivval.quot,10);
    tens=ldivval.rem;
    hunds=ldivval.quot;
    while(1);
}

A 'minimum' program showing how to declare things. stdlib.h, includes the definition of 'ldiv_t'. What you are seeing, is that this is not defined. Something is wrong with your including of this file, or you are trying to declare the variable in the wrong place (remember all variable declarations have to be at the start of a code block), or you have a _very_ old compiler (ldiv, didn't exist about 10 years ago....).

Best Wishes
hayee



Joined: 05 Sep 2007
Posts: 252

View user's profile Send private message

PostPosted: Sun Jun 20, 2010 11:54 pm     Reply with quote

Ttelmah the routine is working fine but as you mentioned that
Quote:
This version will fail if the value is above 327.67

Is there any solution for this.
I will also use thousand's portion which is not in the current theme.
so after changing my current theme it will looks like

thousand,hundred,tens,ones,tenth,hunderedth.

And i think it is not possible using the current function for the thousand value bcoz the limit of the value is 327.67
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 21, 2010 12:04 pm     Reply with quote

You could use sprintf to put formatted ascii numbers in a buffer.
I assume that your number will never be greater than 999.99.
By using the format "%6.2f", if the number has only 1 or 2 digits
on the left side of the decimal, then leading spaces will be added
to the output by the compiler. This allows you to know the position
of each digit in the buffer. You can then get each digit from the
buffer with a line of code. The digit is in ASCII format. You never
told us why you want to do this. Maybe ASCII is the format that
you want. If not, you can convert the digit to binary.
Code:

987.65
 87.60
  7.00

Code:
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

//==========================================
void main()
{
int8 buffer[20];
float value;

value = 987.65;
sprintf(buffer, "%6.2f", value);
puts(buffer);

value = 87.6;
sprintf(buffer, "%6.2f", value);
puts(buffer);

value = 7;
sprintf(buffer, "%6.2f", value);
puts(buffer);


while(1);
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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