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 support@ccsinfo.com

16 bit binary to bcd C++ conversion program
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ttelmah



Joined: 11 Mar 2010
Posts: 19255

View user's profile Send private message

PostPosted: Sun Apr 14, 2013 4:18 am     Reply with quote

Yes, Apologies, it is mishandling values with trailing zeros.
Though it uses an extra bit if storage, this solves this problem, and makes the code a little quicker as well:

Code:

void toBCD(int16 val,int8 * buff) {
   //converts 16bit value, to five BCD digits. Tries to do it fairly
   //efficiently, both in size, and speed.
   int1 temp_bit;
   int8 size=15;
   int1 top_bit=TRUE;
   buff[0]=buff[1]=buff[2]=0;
   do {
      if (!top_bit)
      {
         if ((buff[0] & 0xF)>=5) buff[0]+=3;
         if ((buff[0] & 0xF0)>=0x50) buff[0]+=0X30;
         if ((buff[1] & 0xF)>=5) buff[1]+=3;
         if ((buff[1] & 0xF0)>=0x50) buff[1]+=0X30;
         if ((buff[2] & 0xF)>=5) buff[2]+=3;
      }
      temp_bit=shift_left(&val,2,0);
      shift_left(buff,3,temp_bit);
     
      if (top_bit && temp_bit)
      {
         //Here have the top bit
         top_bit=FALSE;
      }
     
   } while (size--);
}


Best Wishes
ckielstra



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

View user's profile Send private message

PostPosted: Sun Apr 14, 2013 8:23 am     Reply with quote

The original code failed for all values with least significant bits being zero, i.e. multiples of 2,4,8, etc.

Here is another fixed version. It has been optimized by using a local buffer array. The PIC processor is not efficient at handling pointer variables, but the CCS compiler will use hard coded addresses for data on the stack and as such becomes a lot more efficient.

Code:
void toBCD(int16 val,int8 * outBuf) {
   //converts 16bit value, to five BCD digits. Tries to do it fairly
   //efficiently, both in size, and speed.
   int1 temp_bit;
   int8 size = 16;
   int8 buff[3] = {0,0,0};    // For optimization. The PIC processor can address a local array much more efficient than a parameterized address.
   do {
      if ((buff[0] & 0xF)>=5) buff[0]+=3;
      if ((buff[0] & 0xF0)>=0x50) buff[0]+=0X30;
      if ((buff[1] & 0xF)>=5) buff[1]+=3;
      if ((buff[1] & 0xF0)>=0x50) buff[1]+=0X30;
      if ((buff[2] & 0xF)>=5) buff[2]+=3;
      temp_bit=shift_left(&val,2,0);
      shift_left(buff,3,temp_bit);
   } while (--size);
   
   memcpy(outBuf, buff, sizeof(buff));
}


In a short test program I compared the output of the variant posted by Ttelmah today at 11:18 and my version. For all values 0 to 65535 the output was identical. Ttelmah's version clocked at about 85 million instruction counts and the version posted here about twice as fast at 47.5 million.

I tried combining the top_bit optimization but that made things slightly worse. It turns out the top_bit is only skipped for about 12% of the values but adds more total overhead.
Ttelmah



Joined: 11 Mar 2010
Posts: 19255

View user's profile Send private message

PostPosted: Sun Apr 14, 2013 9:26 am     Reply with quote

Interesting. I hadn't realised a local array would be so much quicker.
Should have done. With the local array and fixed indices, the compiler pre-solves and doesn't have to do a table lookup. Know this all too well....

Doing the exit test 'mid loop', and moving the tests after the shift, though more elegant, and avoiding doing the tests on the first pass, costs a couple of instructions....

Looks as if provided you use a local buffer, the simplest is best on this one. Smile

Best Wishes
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 Previous  1, 2
Page 2 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