0

I want to toggle a bit at a given 'offset', I have tried by using typedef to create a new type as "BYTEBUF" and its variable as bitstream. ...

typedef struct{

    char *data;
    unsigned int nb_bytes;
    unsigned long bitlength;
}BYTEBUF;

this is my typedefinition

i want to toggle the bit at a given offset,

i tried using :

bitstream->data[offset]^=1

but many suggest that instead of "offset" it should be "offset/8".

(this is my first question so pls bare for any mistakes)

alter_igel
  • 6,899
  • 3
  • 21
  • 40
jdev
  • 3
  • 2
  • Are you aware of [`std::bitset`](https://en.cppreference.com/w/cpp/utility/bitset)? It is perfectly suited for this type of operation. There is also [`boost::dynamic_bitset`](https://www.boost.org/doc/libs/1_36_0/libs/dynamic_bitset/dynamic_bitset.html) if the size is not known at compile time. – Cory Kramer Apr 22 '20 at 16:31
  • @CoryKramer i am new to c++ , currently not aware about that. Could you pls help me with the expression i felt lil close with that program – jdev Apr 22 '20 at 16:34
  • `data` is a pointer to `char`, which is 8 bits in size. So if `offset` is meant to be a bit-offset and not a byte-offset then you first need to find the right char (multiples of 8) and then toggle the right bit in that char (the remainder). – pallgeuer Apr 22 '20 at 16:35
  • 1
    Does this answer your question? [How do you set, clear, and toggle a single bit?](https://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit) – Asteroids With Wings Apr 22 '20 at 16:43
  • @jdev You can extend those solutions to any number of bytes. Just apply some arithmetic as needed. As you say, `/8` gives you the "right byte", then you can do the required bit operations `%8` on that byte. So yeah basically like in your last comment. The point being that your question is really about performing some arithmetic on sequences of bytes: the fact that you're then going to do bit operations on a byte in that sequence is to some degree an unrelated solved problem. – Asteroids With Wings Apr 22 '20 at 16:51
  • But use a bitset :) – Asteroids With Wings Apr 22 '20 at 16:52
  • @AsteroidsWithWings I am really confused with the 4 options as of now a) bitstream->data[offset]^=1 b) bitstream->data[offset/8]^=(1<data[offset/8]^=(1<data[offset/8]^=(7-(1< – jdev Apr 22 '20 at 16:56
  • @jdev I can't really help you if you just keep throwing symbols at me ;) Break the problem down into parts. Write down on paper what you want to do, and the stages you're taking to do it. – Asteroids With Wings Apr 22 '20 at 17:27

2 Answers2

0

If you want to toggle the bit corresponding to the integer offset, you can calculate:

int bytenum = (offset >> 3);
int bitnum = offset - (bytenum << 3);

Then assuming bitstream is of type BYTEBUF you can do:

bitstream.data[bytenum] ^= (1 << bitnum);

Obviously, you need to be careful that the bytenum is in range (within length of valid memory pointed to by data), that the object has been initialised/constructed properly, etc...

pallgeuer
  • 1,216
  • 1
  • 7
  • 17
0

You can simply use the std::bitset class from the std which offers you all the tools you need for manipulating bits. In your case you would use it like this:

// A array of bits of size 16
std::bitset<16> bits;
// Flip the 6th bit
bits.flip(5);
// Set the 6th bit to one
bits.set(5, true);

If you need to have a struct of variable size (which in your example is the case) then you could do something like this:

struct BYTES
{
  char* bytes;

  // Toggle the byte at position
  // Note that I'm not checking for any overflow
  // which you should definitely do
  void toggle(const size_t position)
  {
    bytes[position/8] ^= 1 << (position % 8);
  }
};

// I'm assuming everything has been allocated properly
BYTES b;
// Toggle the 14th bit
b.toggle(14);

The position/8 gives you the index in the array (as it is an array of char) and position%8 gives you the offset for the single bit inside one char. I would strongly advice you do the arithmetic on a paper yourself to see the picture here!

Thomas Caissard
  • 846
  • 4
  • 10