View previous topic :: View next topic |
Author |
Message |
kel
Joined: 17 Oct 2005 Posts: 68 Location: Brisbane
|
This function returns a digit! |
Posted: Fri Jul 21, 2006 12:13 am |
|
|
The following function returns a single digit from say:12345332.Someone was looking for a similar function before and hope this help.
Code: | #include "stdio.h"
byte Return_A_Single_Digit(long digit,byte post){
byte counter;
for(counter=0; counter < pos; counter++){
digit\=10; /*strip off right-most digit
return digit % 10;
}
}
/*Test programm
void main(void)
{
byte x;
long z;
z=12745563;/*digit to test*/
x=Return_A_Single_Digit(z,3);/*returns 5*/
printf("The digit is: %2i",x);
while(1){}
} |
All you need is to enter the digit position (pos.The index reads from right to left i.e from 12745563,3----0
6----1
5-----2
-
-
1-----8
Hope it helps you..
cheers |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Jul 21, 2006 4:22 am |
|
|
And again we have found another way of attacking the same problem. This must be the 3rd or 4th method found. I'm always surprised how many ways there are to solve the same problem.
There are some errors in your code
Code: | byte Return_A_Single_Digit(long digit,byte post){ | change 'post' -> 'pos'
Code: | for(counter=0; counter < pos; counter++){
digit\=10; /*strip off right-most digit
return digit % 10;
} |
change to
Code: | for(counter=0; counter < pos; counter++){
digit\=10; /*strip off right-most digit
}
return digit % 10; |
|
|
|
iso9001
Joined: 02 Dec 2003 Posts: 262
|
|
Posted: Fri Jul 21, 2006 4:52 pm |
|
|
Yikes.... For looped Div and a Modulos ? If it were me, I'd look into finding a less intensive soultion.
But I'm always working with very time sensitive projects so I could imagine this is fine for most people. |
|
|
sheing3003
Joined: 05 Jul 2006 Posts: 10
|
|
Posted: Fri Jul 21, 2006 7:30 pm |
|
|
something's wrong with it...
i get
The digit is: 1The digit is: 1The digit is: 1The digit is: 1
...suppose to be 5.... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
kel
Joined: 17 Oct 2005 Posts: 68 Location: Brisbane
|
Hi Programmer? |
Posted: Sat Jul 22, 2006 4:24 am |
|
|
Mate i type so fast that i make alot of errors most of the time. But lets concentrate on the good side of the book.It's good that good people are out there to points out these errors.
Besides, the following loop should work just fine.
Code: |
for(counter=0; counter < pos; counter++){
digit\=10; /*strip off right-most digit
return digit % 10;
}
} |
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
Re: Hi Programmer? |
Posted: Sat Jul 22, 2006 9:28 am |
|
|
kel wrote: | Mate i type so fast that i make alot of errors most of the time. But lets concentrate on the good side of the book.It's good that good people are out there to points out these errors.
Besides, the following loop should work just fine.
Code: |
for(counter=0; counter < pos; counter++){
digit\=10; /*strip off right-most digit
return digit % 10;
}
} |
| You type so fast that you didn't change a thing compared to your original post. This is still not working. See my previous post in this thread for a fix. |
|
|
iso9001
Joined: 02 Dec 2003 Posts: 262
|
|
Posted: Sat Jul 22, 2006 4:27 pm |
|
|
Quote: | You type so fast that you didn't change a thing compared to your original post. This is still not working. See my previous post in this thread for a fix. |
LOL. Thats some pretty fast typing! Maybe you should type a little slower mate. You know, make better books. Ckielstra's right, your code doesn't work.
Also, is there a better way to do this then a lot of divs and a mod ? That seems like waste considering how slow divs are, |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Jul 23, 2006 6:19 am |
|
|
iso9001 wrote: | Also, is there a better way to do this then a lot of divs and a mod ? That seems like waste considering how slow divs are, | Often you don't want a single digit but want to split a value in all it's seperate digits. Have a look at http://www.ccsinfo.com/forum/viewtopic.php?t=27600.
If you really want to have a single digit you could modify the optimized version of the reffered thread. |
|
|
Ttelmah Guest
|
|
Posted: Sun Jul 23, 2006 9:39 am |
|
|
In fact I'd say this problem, almost certainly has just about an infinite number of possible solutions!. The particular 'problem' with the CCS division function, is that it does not give you access to the remainder, so 'mod' is implemented by performing a division, multiplying the result by the divisor, and the subtracting this from the original number, making the operation even less efficient than it otherwise could be.
Given how efficient subtraction potentially is, it suggests that a repeated subtraction by the possible 'digit' factors, may well be a fairly efficient solution. In assembler, it'd be possible to save quite a lot of work involved in accessing a 'results' array, by setting up the addressing for the first digit, and just incrementing this.
For generating the entire five digits for an int16, something like:
Code: |
const int16 fact[] = {10000,1000,100,10};
int8 * digits(int16 val) {
int8 ctr=0;
static int8 digs[5];
int8 *ptr;
int8 temp;
ptr=digs;
for (ctr=0;ctr<4;ctr++) {
temp=0;
while (fact[ctr]<=val) {
val-=fact[ctr];
temp++;
}
*ptr++=temp;
}
digs[4]=val;
return digs;
}
|
May in actual 'instruction time', be about as efficient as possible in CCS C, but a lot of testing would be needed to 'tweak' to improve this. A couple of things are done, which may be worth testing. Using a temporary value, and only passing this to the array once the digit is generated, avoids the overhead of multiple array accesses (but at the cost of an extra RAM location). This takes the remainder from the four subtraction loops, and returns this as the final digit.
Remember that the digits are indexed from zero, so:
Code: |
int8 *digvals;
digvals=digits(number);
printf("Third digits = %1d/n",digvals[2]);
|
Will display the third digit.
Best Wishes |
|
|
|