How do you assign a bit from a byte to a bit variable?

Discussion in 'C Programming' started by johannblake, Apr 27, 2006.

  1. johannblake

    johannblake Guest

    I have a variable that is 1 bit wide. I also have a variable that is a
    byte. I want to shift the bits out of the byte into the bit variable
    (one at a time) but am not sure how to do this or whether it is even
    possible. Here is what my code looks like:

    // data is a variable 1 byte in size while bitVariable is 1 bit in
    size. i is a byte.

    for (i = 0; i < 8; i++)
    {
    bitVariable = (data << i) & 0x80;
    }

    I don't believe this will work because there is no indication what is
    really being assigned to bitVariable. My compiler doesn't complain and
    I find that strange. Essentially, I need to shift the bits in "data" to
    an output port on my microcontroller and want to do it as quickly as
    possible.
     
    johannblake, Apr 27, 2006
    #1
    1. Advertisements

  2. johannblake

    Ian Collins Guest

    Do you want the data to be in the MS bit?

    Should it be

    bitVariable = (data >> i) & 0x01;
     
    Ian Collins, Apr 27, 2006
    #2
    1. Advertisements

  3. johannblake

    johannblake Guest

    When shifting the data out of the 'data' variable, the bit in the most
    significant bit position must be assigned to the variable
    'bitVariable'.
     
    johannblake, Apr 27, 2006
    #3
  4. johannblake

    Ian Collins Guest

    Please don't top post.

    So bitVariable is a hardware register?
     
    Ian Collins, Apr 27, 2006
    #4
  5. johannblake

    Mark Guest

    What I would do is

    bitVariable = (data << i) & 0x80 ? 1 : 0;

    Hope this helps
     
    Mark, Apr 27, 2006
    #5
  6. johannblake

    johannblake Guest

    I thought of that as well and am currently doing it that way. But is it
    the most efficient way? An in-line comparison will take up an extra
    clock cycle.

    By the way, I think your example is incorrect. I believe it should be:

    bitVariable = (data << i) & 0x80 ? 0x80 : 0;
     
    johannblake, Apr 27, 2006
    #6
  7. johannblake

    johannblake Guest

    bitVariable is actually a bit-field in a structure. It refers to a
    single output port that consists of 8 outputs.
     
    johannblake, Apr 27, 2006
    #7
  8. johannblake

    johannblake Guest

    Sorry, I screwed up. Your code example is correct.
     
    johannblake, Apr 27, 2006
    #8
  9. johannblake

    Ian Collins Guest

    Please quote some context so your reply makes sense.

    Your method will work, provided you do something with the value each
    time round the loop.
     
    Ian Collins, Apr 27, 2006
    #9
  10. I don't think it matters between

    bitVariable = (data << i) & 0x80 ? 0x80 : 0;

    and
    because if bitVariable is only 1 bit... then why assign a value greater
    than 1?
    And I know my version works cause I compiled it and ran it myself, but
    your way may work also... try it out

    Mark
     
    Mark Laczynski, Apr 27, 2006
    #10
  11. johannblake

    CBFalconer Guest

    Include context. Your articles are meaningless without it. For
    the technique of so doing on the broken google interface to usenet,
    see my sig below.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
    Also see <http://www.safalra.com/special/googlegroupsreply/>
     
    CBFalconer, Apr 27, 2006
    #11
  12. johannblake

    pete Guest

    #include <limits.h>

    for (i = 0; i < CHAR_BIT; i++) {
    bitVariable = data >> CHAR_BIT - 1 - i & 1;
    }
     
    pete, Apr 27, 2006
    #12
  13. johannblake

    pete Guest


    i = CHAR_BIT; /* or i = 8; I suppose */
    while (i-- != 0) {
    bitVariable = data >> i & 1;
    }
     
    pete, Apr 27, 2006
    #13
  14. Mark is right, you should use something similar to

    bitVariable = (data << i) & 0x80 ? 1 : 0;

    See the following:

    ---------------------------------------
    [rwaltman tmp]$ cat bit_test.c

    #include <stdio.h>
    #include <stdlib.h>

    int main(void)
    {
    struct xx { unsigned int bit : 1; } yy ;
    yy.bit = 0x80;
    printf("bit=%d\n", yy.bit);
    yy.bit = 0x01;
    printf("bit=%d\n", yy.bit);
    return EXIT_SUCCESS;
    }
    [rwaltman tmp]$ gcc -ansi -Wall -pedantic -W -o bit_test bit_test.c
    [rwaltman tmp]$ ./bit_test
    bit=0
    bit=1
    [rwaltman tmp]$
     
    Roberto Waltman, Apr 27, 2006
    #14
  15. #include <stdio.h>
    #include <limits.h>

    int main(void)
    {
    unsigned char bit, byte = 0x73, mask = 1u << (CHAR_BIT - 1);
    printf("The original byte is %#04o (%#04x)\n"
    "results of shifting follow:\n", byte, byte);

    while (byte) {
    bit = !!(byte & mask);
    byte <<= 1;
    printf("bit: %o, remaining byte: %#04o (%#04x)\n", bit, byte,
    byte);
    }
    return 0;
    }


    The original byte is 0163 (0x73)
    results of shifting follow:
    bit: 0, remaining byte: 0346 (0xe6)
    bit: 1, remaining byte: 0314 (0xcc)
    bit: 1, remaining byte: 0230 (0x98)
    bit: 1, remaining byte: 0060 (0x30)
    bit: 0, remaining byte: 0140 (0x60)
    bit: 0, remaining byte: 0300 (0xc0)
    bit: 1, remaining byte: 0200 (0x80)
    bit: 1, remaining byte: 0000 (0000)
     
    Martin Ambuhl, Apr 27, 2006
    #15
  16. A shift probably takes longer, but it's worth a try. Depending on the CPU,
    Mark's version will probably require a comparison and a branch. For one
    common CPU, shifts of four or less are faster than a comparison and a branch
    even with good branch prediction by the CPU. This could result in slightly
    faster code.

    bitVariable = ((data << i) & 0x80) >>7);

    A few people here will scream since you've used non-portable code. You've
    assumed CHAR_BIT is 8.


    Rod Pemberton
     
    Rod Pemberton, Apr 28, 2006
    #16
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.