Thread: bitset + memcpy

  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    486

    bitset + memcpy

    Hey all

    I am pretty new to messing around with the bits of a system, and I am trying to learn to use bitsets as a way to solve a few problems I am having. My question is this:

    is there a way to use memcpy to copy the bits of say an integer into a certain place in a bitset? Say I want to make a key from my three ints such that the first 8 bits of the bitset are the 8 bits of integer one, the second 8 bits of bitset and the 8 bits of integer two, etc.

    I want to do something like this:

    Code:
    #include <bitset>
    #include <iostream>
    #include <limits>
    #include <cstring>
    using namespace std;
    
    int main( )
    {
       bitset<24> key;
       int num1 = 5;
       int num2 = 7;
       int num3 = 2;
    
       memcpy(&key, &num3, 8);
       memcpy(&key+8, &num2, 8);
       memcpy(&key+16, &num1, 8);
       cout  << key << endl;
    }
    Since bits are reversed, I would like the output from that to be:

    00000101 00000111 00000010, but it most definitely isn't. I am completely lost in the fact that numbers are reversed in their binary representation on little endian systems (apparently?) and would really appreciate if someone could explain to me a little better than the tutorials I have found so far.

    Also, declaring key as

    Code:
    bitset<24> *key
    just segfaults me when i try to use it like that, so is there anything diffferent about pointers to bitsets than regular pointers? I usualyl use c, so c++ is a little bit new to me.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    That certainly won't work. For several reasons.
    1. &key gives you the address of the object itself (unless operator & for the object has been overridden, which I doubt in this case).
    2. The last parameter of memcpy() being the size should be 1 if you are copying 8 bits.
    3. If you have the "right" endianness, you get the wrong data in the memcpy, since you would be copying the byte that has the lowest memory address, not the one with the least significant bit values. [This assumes the other things above aren't already making this impossible].

    So, I would say what you are doing is wrong, and there is no trivial way to fix it.

    What are you ACTUALLY trying to do? [What is the actual problem you are trying to solve, not "how do I get bits into my bitset quickly", but the overall problem - or are you simply messing about?].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    No, you don't use memcpy for bit-fiddling (it works on bytes anyway, + you have no idea how the memory representation of a class like bitset might look like + pointer arithmetics definitely won't work for single bits).

    For bit-fiddling bitwise operators are used. Use or to combine numbers and bit-shifts for shifting bits 8 or 16 positions.

    Code:
    key = (num1 << 16) | (num2 << 8) | num3;
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    Right now I am just screwing around. I didn't really expect memcpy to work, I was just hoping there was a lazier way of doing it than bit shifts ^_^ since I have never really worked with them before.

    The eventual problem I need to do is to interleave the bits of three doubles, so that key will alternate between their bits.

    ie (assuming 5 bit numbers)

    11001
    10010
    11100

    would become

    111101001010100

    For now, I just want to understand how bitsets work and get a feel for bitshift operations.
    Last edited by KBriggs; 08-14-2009 at 11:47 AM.

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by KBriggs View Post
    I am completely lost in the fact that numbers are reversed in their binary representation on little endian systems (apparently?) and would really appreciate if someone could explain to me a little better than the tutorials I have found so far.
    Nothing is reversed. Take the difference between English and Hebrew writing systems. English goes left to right, Hebrew goes right to left. This doesn't mean that one of them is "reversed," it means they are different. To say that Hebrew, for instance, is written "backwards" is no more justifiable than saying English is written backwards.

    To understand endianness, first remember that the order of bits is irrelevant. Endianness describes the order of the BYTES within a multi-byte quantity. Within each byte, the bits "are what they are," i.e. there is a most significant bit and a least significant bit, and bits in between. Trying to comprehend the address order of bits within a byte is fruitless since such an ordering doesn't exist -- bits do not have addresses, only bytes do. There is ONLY "most signficant" and "least significant."

    (Of course, when you need to serialize bits, such as for transmission on a modem, you need to decide which bit comes first in the serial bit stream. But this problem is irrelevant to computation)
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  6. #6
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    Nothing is reversed. Take the difference between English and Hebrew writing systems. English goes left to right, Hebrew goes right to left. This doesn't mean that one of them is "reversed," it means they are different. To say that Hebrew, for instance, is written "backwards" is no more justifiable than saying English is written backwards.
    That's jsut splitting hairs. What I meant was that, comparing an array with n elements to a bitset with nelements, the nth element is the last one in the array, but the first (leftmost?) one in the bitset.

    There is ONLY "most signficant" and "least significant."
    Fair enough - on a little endian system, the the MSB on the left or the right?

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by KBriggs View Post
    That's jsut splitting hairs. What I meant was that, comparing an array with n elements to a bitset with nelements, the nth element is the last one in the array, but the first (leftmost?) one in the bitset.



    Fair enough - on a little endian system, the the MSB on the left or the right?
    >> That's jsut splitting hairs.

    No, it was concise. To say that endianness is "reversed" is misleading and incorrect. The bytes are swapped - nothing more.

    >> Fair enough - on a little endian system, the the MSB on the left or the right?

    Strictly speaking, neither! In programming, "left" and "right" generally refer to bit positions, and are endian-neutral terms. Anyway, on LE systems the least significant byte comes first (in the sense that if you were to reconstruct it from a stream of bytes, the first byte processed would be the lowest byte of the word).

    >> is there a way to use memcpy to copy the bits of say an integer into a certain place in a bitset?

    As a rule of thumb, using memcpy/memset or otherwise messing with bits should never be used on non-simple types (eg: most classes) since it can often corrupt important state information.

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by KBriggs View Post
    Fair enough - on a little endian system, the the MSB on the left or the right?
    That depends whether the computer is upside down or not.

    (The question is nonsense)
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 14
    Last Post: 06-28-2006, 01:58 AM
  2. Memcpy(); Errors...
    By Shamino in forum C++ Programming
    Replies: 4
    Last Post: 03-24-2006, 11:35 AM
  3. Using bitset class inside another
    By Dhekke in forum C++ Programming
    Replies: 3
    Last Post: 07-26-2005, 06:50 AM
  4. memcpy with 128 bit registers
    By grady in forum Linux Programming
    Replies: 2
    Last Post: 01-19-2004, 06:25 AM
  5. memcpy
    By doubleanti in forum C++ Programming
    Replies: 10
    Last Post: 02-28-2002, 04:44 PM