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