Change some bits in an integer

Oct 22, 2015 at 6:22pm
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 Oct 22, 2015 at 6:44pm
Oct 22, 2015 at 6:58pm
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 Oct 22, 2015 at 7:04pm
Oct 22, 2015 at 7:36pm
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......
Oct 22, 2015 at 11:12pm
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;
}
Oct 23, 2015 at 10:15am
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??
Oct 23, 2015 at 6:08pm
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;
Oct 23, 2015 at 6:22pm
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.
Oct 23, 2015 at 7:33pm
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.
Oct 23, 2015 at 8:20pm
Ah. I misunderstood the question. Thanks Duoas for correcting me.
Oct 23, 2015 at 11:55pm
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.
Oct 24, 2015 at 3:22am
Make your to verify for big and little endian.
Oct 24, 2015 at 4:53pm
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.
Oct 25, 2015 at 3:30pm
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.