Change some bits in an integer

Hello guys!!

I'm trying to change some information with an integer, what I want to do is basically get an integer and change its most significant byte and its less significant byte...for example if I have this byte 10101010 it would be converted in 01010101...it must be done for the most significant and for the less significant but what is more important is to be able to distinguish different bytes and how to manage a bit level the information.....does anyone come up with an idea???, thanks!!

Last edited on
I can't say that I well-understand your question. I get the impression that you are mixing the words 'byte' and 'bit'.

To change the least significant bit (meaning, it is the bit with the least value), modify by bit operations using 1.

set least-significant bit
value |= 1; .
1100 | 1 → 1101
1101 | 1 → 1101


flip least-significant bit
value ^= 1; .
1100 ^ 1 → 1101
1101 ^ 1 → 1100


clear least-significant bit
value &= ~1; .
1100 & ~1 → 1100
1101 & ~1 → 1100


get the least-significant bit's value
least_bit = value & 1; .
1100 & 1 → 0
1101 & 1 → 1



To modify the most significant bit, you need that bitmask to be set in the most-significant bit position. Get it with some bit-math and #include <limits>:

    T high_bit_mask = T(1) << (std::numeric_limits<T>::digits - 1)

This presupposes that T is an unsigned integer type. (You should not be performing bit hacks on signed types. Cast them as unsigned if you must.)

Thereafter, modifying the most-significant bit is the same as with the least, only using a different bitmask:

set most-significant bit
value |= high_bit_mask; .
0100 | 1000 → 1100
1100 | 1000 → 1100


flip most-significant bit
value ^= high_bit_mask; .
0100 ^ 1000 → 1100
1100 ^ 1000 → 0100


clear most-significant bit
value &= ~high_bit_mask; .
0100 & ~1000 → 0100
1100 & ~1000 → 0100


get the most-significant bit's value
most_bit = value & high_bit_mask; .
0100 & 1000 → 0000
1100 & 1000 → 1000


Or, if you just want a 0 or a 1:
most_bits_value = (value >> digits) & 1; .
(0100 >> 3) & 1 → 0
(1100 >> 3) & 1 →1



So when you have a byte 10101010 and you flip the most- and least-significant bits, you'll wind-up with 00101011.


Was that what you were asking about?

[edited for clarity]
Last edited on
yes, In part...thanks!!! for sure I would need what you explained to do what I want to do....but I think an integer is composed by 4 bytes....1 byte 2 byte 3 byte 4 byte.....I want to do a nor(if there is 1 to 0 if there is 0 to 1) operation in every bit of 1 byte and 4 byte......
The integer is taken as a whole. To change the first and last bytes, you can either use bit operations, or cast to an array of bytes.

1
2
3
4
5
6
7
8
9
10
11
int swap_first_and_last_bytes_in_int( int n )
{
  union 
  {
    int n;
    unsigned char bs[ sizeof(n) ];
  } x;
  x.n = n;
  std::swap( x.bs[0], x.bs[ sizeof(n)-1 ] );
  return x.n;
}
It was really helpful, I achieved what I wanted to do....I did this...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <iostream>

using namespace std;

unsigned int flip_first_last(unsigned int n )
{
union 
  {
   unsigned int n;
    unsigned char bs[ sizeof(n) ];
  } x;
  x.n = n;
  x.bs[0] = ~x.bs[0];
  x.bs[sizeof(n)-1] = ~x.bs[sizeof(n)-1];
  return x.n;
}
 
int main(){
	unsigned int a = 4278190271;
	cout<<flip_first_last(a);
	a = 64;
	cout<<endl;
	cout<<flip_first_last(a);
}


very clever the idea to use an union to refer to the same space of memory then you can divided that space in a char array because each element occupies exactly 1 byte....but I wonder something, I have been trying to look for an specific instruction to address to a specific byte in C++ and apparently there is not....is that true?? will i have to use always this kind of ingenuity??
The trick works because you are swapping the first and last -- endianness doesn't matter.

But if you want, for example, to address specifically the first or last byte, you must use the appropriate bit operations:

1
2
unsigned char lsb = value_u32 & 0xFF;
unsigned char msb = value_u32 >> 24;
It's a one-liner: int newval = oldval ^ 0xff0000ff; This assumes that you really do mean the most significant byte and not the first byte stored in memory.
That flips the bits in the first and last bytes of the value.

If you want to swap the bytes, you must resort to either a union hack or multiple bit extraction, mask, and set operations.
Ah. I misunderstood the question. Thanks Duoas for correcting me.
I didn't understand the question at first either. (I'm still not sure I entirely understand what is being asked.) But Winsu seems to be happy with the answers...

And I wasn't trying to correct you, just clarify our different answers' actions -- both useful.
Make your to verify for big and little endian.
As I indicated above, simply swapping the high and low bytes, or flipping their bits, is an endianness agnostic operation.

I also indicated that bit operations are necessary if endianness does matter, and gave examples.
My first question( the first post ) was if there was a way to do operation with just a single byte in an integer....in fact ii didn't matter if it was the most significant, the least significant or one between others...it was resolved with the union solution....after that I questioned the possibility of changing any bit in an integer(or double or long...etc), and it's apparently possible masking and doing some more operation.... After everything I found a library <bitset> which has some instruction to modify a bit level....

for example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// bitset::set
#include <iostream>       // std::cout
#include <bitset>         // std::bitset

int main ()
{
  std::bitset<4> foo;

  std::cout << foo.set() << '\n';       // 1111
  std::cout << foo.set(2,0) << '\n';    // 1011
  std::cout << foo.set(2) << '\n';      // 1111

  return 0;
}


This operation don't look useful to flip a whole byte or swap two byte....for that I would go to the union solution, nevertheless this library looks interesting...
Topic archived. No new replies allowed.