Thread: C how to Shift bits in BCD

  1. #1
    Registered User
    Join Date
    Feb 2010
    Posts
    72

    C how to Shift bits in BCD

    Hi, i have a binary data that is coded in BCD bytes , example: AB(one BCD byte) in BCD is the concat of A and B in binary, so : AB = 1010(A)1011(B), and i want a function that can reverse the my BCD byte, the result will be :
    Code:
    shift_function(AB) = 1011(B)1010(A)
    Thanks.
    Last edited by evariste; 12-16-2010 at 03:14 PM. Reason: correct the shift_function parameter

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    So you want the high and low nibbles of the byte?
    Code:
    int main(void)
    {
    ...
    int a, b;
    shift_function(bcd_byte, &a, &b);
    ...
    }
    
    void shift_function(int bcd_byte, int *high, int *low)
    {
      *high = bcd_byte >> 4;
      *low = bcd_byte & 0xF;
    }
    If you understand what you're doing, you're not learning anything.

  3. #3
    Registered User
    Join Date
    Feb 2010
    Posts
    72
    Thanks for the reply,
    i try your code (you shift 4 bits) and get a strange result:

    Code:
    #include <stdio.h>
    
    void shift_function(unsigned bcd_byte, int *high, int *low)
    {
      *high = bcd_byte >> 4;
      *low = bcd_byte & 0xF;
    }
    
    int
    main()
    {
            int a, b;
            unsigned char bcd_byte = 0x34;
    
            printf("Before : %x\n", bcd_byte);
            shift_function(bcd_byte, &a, &b);
            printf("After : %x\n", bcd_byte);
    
            return 0;
    }
    Last edited by evariste; 12-16-2010 at 03:38 PM. Reason: modify bcd_byte

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    What exactly are you expecting to happen? You pass a value bcd_byte to a function, not its address, and you are expecting the original variable to be changed? Why aren't you looking at a's and b's values? The function doesn't actually change bcd_byte. How could it? It's a value pass.

    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    For one, you don't really have BCD. BCD is binary coded decimal, which means each nibble can only store valid decimal values (0-9), so you can't have A and B representing 10 and 11. Regardless, you want to switch the high and low nibbles, so try something like this:
    Code:
    void swap_nibbles(unsigned char *c)
    {
        *c = (*c << 4) | (*c >> 4)
    }
    
    int main(void)
    {
        unsigned char c = 0xab;
        swap_nibbles(&c);
        return 0;
    }
    EDIT: Fixed a typo in my code sample. Thanks ncward!
    Last edited by anduril462; 12-16-2010 at 10:29 PM.

  6. #6
    Registered User
    Join Date
    Feb 2010
    Posts
    72
    Quote Originally Posted by quzah View Post
    What exactly are you expecting to happen? You pass a value bcd_byte to a function, not its address, and you are expecting the original variable to be changed? Why aren't you looking at a's and b's values? The function doesn't actually change bcd_byte. How could it? It's a value pass.

    Quzah.
    You're absolutly right i'm sorry. But this function does not do what i'm expecting.

  7. #7
    Registered User
    Join Date
    Feb 2010
    Posts
    72
    Code:
    #include <stdio.h>
    
    unsigned char shift_function(char bcd_byte)
    {
      int high, low;
    
      high = bcd_byte >> 4;
      low = bcd_byte & 0xF;
    
      return low|high;
    }
    
    int
    main()
    {
    
            char bcd_byte = 0x34;
            unsigned char result;
    
            printf("Before : %x\n", bcd_byte);
            result = shift_function(bcd_byte);
            printf("After : %x\n", result);
           
            return 0;
    }
    I try this code but?

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    But you forgot to shift low over 4 bits before ORing it with high:
    Code:
      low = (bcd_byte & 0xF) << 4;
    or just
    Code:
      low = bcd_byte << 4;

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    But what? Stop giving cryptic half-sentence responses, and tell us what you expect to see in your output that you aren't seeing.


    Quzah.
    Hope is the first step on the road to disappointment.

  10. #10
    Registered User
    Join Date
    Feb 2010
    Posts
    72
    Quote Originally Posted by anduril462 View Post
    But you forgot to shift low over 4 bits before ORing it with high:
    Code:
      low = (bcd_byte & 0xF) << 4;
    or just
    Code:
      low = bcd_byte << 4;
    Thanks anduril462 problem solved.

  11. #11
    Registered User
    Join Date
    Feb 2010
    Posts
    72
    Quote Originally Posted by quzah View Post
    But what? Stop giving cryptic half-sentence responses, and tell us what you expect to see in your output that you aren't seeing.


    Quzah.
    Sorry problem solved thanks.

  12. #12
    Registered User
    Join Date
    Dec 2010
    Posts
    5
    Quote Originally Posted by anduril462 View Post
    For one, you don't really have BCD. BCD is binary coded decimal, which means each nibble can only store valid decimal values (0-9), so you can't have A and B representing 10 and 11. Regardless, you want to switch the high and low nibbles, so try something like this:
    Code:
    void swap_nibbles(unsigned char *c)
    {
        *c = (*c << 4) && (*c >> 4)
    }
    
    int main(void)
    {
        unsigned char c = 0xab;
        swap_nibbles(&c);
        return 0;
    }
    Code:
    void swap_nibbles(const char *c)
         *c = (*c << 4) | (*c >> 4);
    I think is what you meant.

  13. #13
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    D'oh! Yeah, that's it. Thanks.

  14. #14
    Registered User
    Join Date
    Feb 2010
    Posts
    72
    Quote Originally Posted by ncward View Post
    Code:
    void swap_nibbles(const char *c)
         *c = (*c << 4) | (*c >> 4);
    I think is what you meant.
    Thanks, TOPIC is closed .

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bits and Addresses
    By jcafaro10 in forum C++ Programming
    Replies: 3
    Last Post: 03-15-2009, 02:55 PM
  2. still problems with ceasar shift
    By trevordunstan in forum C Programming
    Replies: 2
    Last Post: 09-14-2008, 01:49 AM
  3. Ceasar Shift program
    By trevordunstan in forum C Programming
    Replies: 11
    Last Post: 09-11-2008, 09:40 PM
  4. SDLKey to ASCII without unicode support?
    By zacs7 in forum Game Programming
    Replies: 6
    Last Post: 10-07-2007, 03:03 AM
  5. Writing binary data to a file (bits).
    By OOPboredom in forum C Programming
    Replies: 2
    Last Post: 04-05-2004, 03:53 PM