View previous topic :: View next topic |
Author |
Message |
Vovachess
Joined: 15 Mar 2004 Posts: 33 Location: Swiss
|
Converting bytes |
Posted: Tue Aug 23, 2005 7:43 am |
|
|
Hello All
I d like to know how to pick out from int value 125 values 1,2,5?
One way is like:
(timesumme/100)%10;
(timesumme/10)%10;
timesumme%10;
Are there easier for prozessor ways? Using <<, >>,&...
Thanks for ideas. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Aug 23, 2005 7:52 am |
|
|
depends on what you want to do with the values.
For example, if you are try to display the digits, then converting to a string using printf works well. Another option might be to convert to BCD and access the numbers by nibbles. |
|
|
Vovachess
Joined: 15 Mar 2004 Posts: 33 Location: Swiss
|
|
Posted: Tue Aug 23, 2005 7:56 am |
|
|
I wonder to have some exmpls. I will use them to display as a separate value.
Actualy I want to do my code smaller then now. Are there any exmpls how to divide with <<,>>, &......? |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Aug 23, 2005 8:14 am |
|
|
Is 125 decimal or hex?
You can divide 10 with >>.
However, in hex each digit is 4 bits or >>4. |
|
|
Vovachess
Joined: 15 Mar 2004 Posts: 33 Location: Swiss
|
|
Posted: Tue Aug 23, 2005 8:16 am |
|
|
125 is dec, not hex!
How to divide it correctly? exmlps...... |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Aug 23, 2005 8:48 am |
|
|
Quote: | Actualy I want to do my code smaller then now. Are there any exmpls how to divide with <<,>>, &......? | These instructions are only optimal when doing calculations with values that are multiples of 2 but won't do the trick with decimal values.
Example 1:
Code: | char AsciiVal[4];
sprintf(AsciiVal, "%d", 123);
// Now the array contains:
// AsciiVal[0] == '1'
// AsciiVal[1] == '2'
// AsciiVal[2] == '3'
// AsciiVal[3] == \0 |
Example 2:
Code: | int8 Value;
int8 Remainder;
Value = 123;
while (Value)
{
Remainder = Value % 10;
Value = Value / 10;
putc(Remainder); // or use Remainder + '0' for ASCII output
} |
Example 3, using the div() function:
Code: | #include <STDLIB.H>
div_t idiv;
int8 Value;
int8 Remainder;
Value = 123;
while (Value)
{
idiv = div(Value, 10);
Remainder = idiv.rem;
Value = idiv.quot;
putc(Remainder); // or use Remainder + '0' for ASCII output
} |
In my experience the div() function from example3 uses 80 to 200 bytes more than a combination of / and % operators so I stopped using it. |
|
|
Vovachess
Joined: 15 Mar 2004 Posts: 33 Location: Swiss
|
|
Posted: Tue Aug 23, 2005 9:01 am |
|
|
Thank. You use always div!!!! It is to long for controller. I d like to do the same but with simlpe operation ... like >>,<<, &. Are there any ideas how to do it? |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Aug 23, 2005 10:01 am |
|
|
Vovachess wrote: | Thank. You use always div!!!! It is to long for controller. I d like to do the same but with simlpe operation ... like >>,<<, &. |
ckielstra wrote: | These instructions are only optimal when doing calculations with values that are multiples of 2 but won't do the trick with decimal values. | Which part don't you understand?
As far as I know there is no quick method to split an 8 bit binary value into seperate decimal digits. One way to minimize the code size is to do the conversion in a loop like my Example1. The two divisions in Example1 take 14 bytes, if that is a problem for your program size I'm sure there is another problem in the architecture of your program.
For other more efficient methods you need to give us more information about your application, for example the minimum and maximum values you need to handle, what calculations you want to do on the variables, etc. Possible solutions I'm thinking of are HEX or BCD arithmetic but this depends on your application. |
|
|
dima2882
Joined: 13 Jul 2005 Posts: 25 Location: Maryland
|
|
Posted: Tue Aug 23, 2005 2:04 pm |
|
|
Here is the way I did this:
Code: |
// Function converts a decimal integer into a binary number, and writes to a globally asssigned array
// The global array
int RPMbin[16];
void dec2bin(int RPMdec)
{
int temp[16];
int k = 0, n = 0;
int remainder;
// Write all zeros if decimal number to be converted is a zero
if (RPMdec == 0)
{
for(k = 0; k <= 16; k++)
{
RPMbin[k] = 0;
printf("%d",RPMbin[k]);
}
return;
}
// Perform this routine if number to be converted is not a zero
else
{
k = 0;
while(RPMdec > 0)
{
remainder = RPMdec % 2;
RPMdec = RPMdec / 2;
temp[k] = remainder;
k++;
}
// Fill in unused numbers in array with zeros
while(k <= 16)
{
temp[k] = 0;
k++;
}
// Reverse order of numbers to conform with Intel little-endian notation
for(k = 16; k >= 0; k--)
{
RPMbin[n] = temp[k];
n++;
}
}
return;
}
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Aug 24, 2005 3:52 am |
|
|
dima2882,
Vovachess wants to convert an integer to it's decimal characters, not an integer to binary.
Also your code for dec2bin() contains several errors:
1) You are processing from bit 0 up to and including bit 16, a total of 17 bits. This is a major bug causing memory violations in at least 3 locations.
2) In CCS the default size of an integer is 8 bits and unsigned as opposed to your code that assumes 16 bit signed integers.
Below I posted the corrected code. Code: | // Function converts a decimal integer into a binary number, and writes to a globally asssigned array
// The global array
int RPMbin[16];
void dec2bin(int16 RPMdec) // changed int to int16
{
int temp[16];
signed int8 k = 0; // Changed int to signed int 8
int n = 0;
int remainder;
// Write all zeros if decimal number to be converted is a zero
if (RPMdec == 0)
{
for(k = 0; k <= 15; k++) // Changed 16 to 15
{
RPMbin[k] = 0;
printf("%d",RPMbin[k]);
}
return;
}
// Perform this routine if number to be converted is not a zero
else
{
k = 0;
while(RPMdec > 0)
{
remainder = RPMdec % 2;
RPMdec = RPMdec / 2;
temp[k] = remainder;
k++;
}
// Fill in unused numbers in array with zeros
while(k <= 15) // Changed 16 to 15
{
temp[k] = 0;
k++;
}
// Reverse order of numbers to conform with Intel little-endian notation
for(k = 15; k >= 0; k--) // Changed 16 to 15
{
RPMbin[n] = temp[k];
n++;
}
}
return;
} |
One more remark: I don't understand your bit swapping for little-endian notation. Big- and Little endian refers to the byte order but you are reversing the order of all bits which does not give the same result. |
|
|
Ttelmah Guest
|
|
Posted: Wed Aug 24, 2005 4:12 am |
|
|
If the numbers are less than 100 (0-99), then you can do a faster version of the standard division. Basically:
Code: |
int8 mask=8;
int8 comp=80;
int8 res=0;
while (mask) {
if (val>comp) {
res+=mask;
val-=comp;
}
comp/=2;
mask/=2;
}
|
The compiler should perform the two 'divisions', by simple rotation, and if this is called with a binary value in 'val', at the end of the routine, 'res' will contain the top decimal digit, and 'val' will contain the low digit. Add '0' to each to turn them into text form.
This performs the most basic binary division, in about the smallest form possible, and should be both faster and smaller than the standard routine.
Since there are only two possible values for the top digit, extending this by just testing for it being above 100 and 200 respectively, should still be a pretty 'tight' version.
Best Wishes |
|
|
sseidman
Joined: 14 Mar 2005 Posts: 159
|
|
Posted: Wed Aug 24, 2005 6:29 am |
|
|
Vovachess wrote: | Thank. You use always div!!!! It is to long for controller. I d like to do the same but with simlpe operation ... like >>,<<, &. Are there any ideas how to do it? |
Why in the world would you want to do something like this in a controller?? If it's for display purposes (the only reason I can think of), you'd be updating faster than the display can handle, and nobody would be able to read the output if it could.
Cut down the rate of display to maybe 10/second. Offload the current value to a display buffer, and do what you need to do to it in a display subroutine. Make sure your main control loop is interrupt driven. This way, you no longer care how long these calculations take.
Scott |
|
|
|