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

Converting bytes

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



Joined: 15 Mar 2004
Posts: 33
Location: Swiss

View user's profile Send private message Visit poster's website ICQ Number

Converting bytes
PostPosted: Tue Aug 23, 2005 7:43 am     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Tue Aug 23, 2005 7:52 am     Reply with quote

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

View user's profile Send private message Visit poster's website ICQ Number

PostPosted: Tue Aug 23, 2005 7:56 am     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Tue Aug 23, 2005 8:14 am     Reply with quote

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

View user's profile Send private message Visit poster's website ICQ Number

PostPosted: Tue Aug 23, 2005 8:16 am     Reply with quote

125 is dec, not hex!
How to divide it correctly? exmlps......
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Aug 23, 2005 8:48 am     Reply with quote

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

View user's profile Send private message Visit poster's website ICQ Number

PostPosted: Tue Aug 23, 2005 9:01 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Aug 23, 2005 10:01 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Aug 23, 2005 2:04 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Aug 24, 2005 3:52 am     Reply with quote

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







PostPosted: Wed Aug 24, 2005 4:12 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Aug 24, 2005 6:29 am     Reply with quote

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