Thread: bit mux / demux

  1. #1
    Registered User
    Join Date
    Sep 2002
    Posts
    1

    Unhappy bit mux / demux

    Hi,

    I'm trying to implement a mux / demux in C. The basic idea is, given an input buffer of char[], i want to be able to read the required number of bits and place them in the destination buffer and then read the next number of bits and place them in the next destination buffer, etc...

    eg

    given a char[]

    take first 3 bits and put into buffer a
    take next 4 bits and put into buffer b
    take next 5 bits and put into buffer c
    take next 3 bits and put into buffer a
    take next 4 bits and put into buffer b
    .... etc


    and for the demux i would like to be able to reverse the process, so that i can recreate the char[].

    Anyone have any ideas??? I've thought about bit shifting and stuff but you can only shift bits in a byte and can't shift an entire array right??

    Thanks for your help.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Simple enough
    Code:
    #include <stdio.h>
    #include <limits.h>
    
    int getBits ( char *buff, int *bitpos, int numbits ) {
        int byte = *bitpos / CHAR_BIT;
        int bit  = *bitpos % CHAR_BIT;
        int mask = (1<<numbits)-1;
        int word = buff[byte] | (buff[byte+1]<<8);
    
        *bitpos += numbits;
        return ( word >> bit ) & mask;
    }
    
    int main ( ) {
        char buff[] = "hello world";
        int  bitpos=0;
        printf( "3=%x\n", getBits(buff,&bitpos,3) );
        printf( "4=%x\n", getBits(buff,&bitpos,4) );
        printf( "5=%x\n", getBits(buff,&bitpos,5) );
        printf( "3=%x\n", getBits(buff,&bitpos,3) );
        printf( "4=%x\n", getBits(buff,&bitpos,4) );
        printf( "5=%x\n", getBits(buff,&bitpos,5) );
        return 0;
    }

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Simple enough


    Salem, how the hell did you come up with that??!

    Anyway, very nice work
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    I think the code posted by Salem may be incorrect.

    Code:
    #include <stdio.h>
    #include <limits.h>
    
    int getBits ( char *buff, int *bitpos, int numbits ) {
        int byte = *bitpos / CHAR_BIT;
        int bit  = *bitpos % CHAR_BIT;
        int mask = (1<<numbits)-1;
        int word = buff[byte] | (buff[byte+1]<<8);
    
        *bitpos += numbits;
        return ( word >> bit ) & mask;
    }
    
    void test(const char *buff)
    {
        int  bitpos=0;
        printf( "3=%x\n", getBits(buff,&bitpos,3) );
        printf( "4=%x\n", getBits(buff,&bitpos,4) );
        printf( "5=%x\n", getBits(buff,&bitpos,5) );
        printf( "3=%x\n", getBits(buff,&bitpos,3) );
        printf( "4=%x\n", getBits(buff,&bitpos,4) );
        printf( "5=%x\n", getBits(buff,&bitpos,5) );
    }
    
    int main(void)
    {
        /* LSB 0001:1110-0000:0001-1119:0000 MSB */
        /*     3334:4445-5555:3334-4445:5555     */
        const char buf1[] = { 0x78, 0x80, 0x07 };
        /* LSB 0101:0101-1010:1010-0101:0101 MSB */
        /*     3334:4445-5555:3334-4445:5555     */
        const char buf2[] = { 0xAA, 0x55, 0xAA };
        /* LSB 1010:1010-0101:0101-1010:1010 MSB */
        /*     3334:4445-5555:3334-4445:5555     */
        const char buf3[] = { 0x55, 0xAA, 0x55 };
        test(buf1);
        puts("---");
        test(buf2);
        puts("---");
        test(buf3);
        return 0;
    }
    
    /* my (annotated) output
    3=0
    4=f
    5=0
    3=0
    4=f
    5=0
    ---
    3=2
    4=5
    5=1f  <<< incorrect, should be 0xB
    3=5
    4=4
    5=15
    ---
    3=5
    4=a
    5=14
    3=2
    4=f   <<< incorrect, should be 0xB
    5=a
    */
    I haven't come up with a better solution yet, I just wanted to point this out. Also, should the 8 in the following have been CHAR_BIT?
    Code:
    int word = buff[byte] | (buff[byte+1]<<8);

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    The algorithm is good, it's just the implementation which is off
    Code:
    int getBits ( const unsigned char *buff, int *bitpos, int numbits ) {
        int byte = *bitpos / CHAR_BIT;
        int bit  = *bitpos % CHAR_BIT;
        unsigned int mask = (1<<numbits)-1;
        unsigned int word = buff[byte] | (buff[byte+1]<<CHAR_BIT);
    
        *bitpos += numbits;
        return ( word >> bit ) & mask;
    }
    My mistake for testing with ascii data not binary data

    The problem was the sign extension when converting bytes with the MSB set (eg. 0xaa) to ints, resulting in all the most significant bits being set.

    > Also, should the 8 in the following have been CHAR_BIT?
    Yes

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 11-10-2005, 10:53 AM
  2. porting application from 32 bit to 64 bit error
    By gandalf_bar in forum Linux Programming
    Replies: 1
    Last Post: 09-14-2005, 09:20 AM
  3. Bit processing in C
    By eliomancini in forum C Programming
    Replies: 8
    Last Post: 06-07-2005, 10:54 AM
  4. Array of boolean
    By DMaxJ in forum C++ Programming
    Replies: 11
    Last Post: 10-25-2001, 11:45 PM
  5. bit conversions
    By wazilian in forum C Programming
    Replies: 4
    Last Post: 10-25-2001, 08:59 PM