简体   繁体   中英

How to set a Bit in an Integer without using a bitmask

I want to set a bit on an integer but without creating a bitmask to help me.

Example: a=128 and masc=00000001 ...a&masc=10000001

Example on how to do it with a bitmask:

int y,masc;
int a=128;
masc=0x01;
y=a|masc;
cout<<y;

The question now is: Is there a way to do this without the bitmask and if possible shorter then this code?

There are a number of different ways of doing this but it's tricky to offer a 'better' solution without knowing why simply using a bit mask is a problem. For example, you could use a helper function along the lines of:

template< typename BITS> inline BITS set_bit(BITS data, size_t pos, bool val)
{
    return ( val ) ? data | ( 1 << pos ) : data & ~ ( 1 << pos );
}

unsigned int a = 128;
a = set_bit(a, 0, true);
std::cout << a << std::endl;   // gives 129 = 10000001
a = set_bit(a, 4, true);
std::cout << a << std::endl;   // gives 145 = 10010001
a = set_bit(a, 7, false);
std::cout << a << std::endl;   // gives 17  = 00010001

(Note that I've not added any bounds checking to this on the pos parameter)

Another way to do this might be to use a bitfield which allows you to declare variable names for individual bit and groups of bits of a larger type as follows:

struct MyBits {
    unsigned int alpha : 1,
                 beta : 1,
                 gamma : 1;
};

MyBits b;
b.alpha = 1;
b.gamma = 1;

std::cout << b.alpha << std::endl;  // gives 1
std::cout << b.beta << std::endl;   // gives 0
std::cout << b.gamma << std::endl;  // gives 1

A third way - although this is not strictly using an int as such - might be to use a bitset to achieve a similar job:

#include <bitset>

std::bitset<8> c;
c[0] = true;
c[2] = true;

std::cout << c[0] << std::endl; // gives 1
std::cout << c[1] << std::endl; // gives 0
std::cout << c[2] << std::endl; // gives 1

All have their advantages and disadvantages. It largely depends on the motivating factors behind your question.

In C++ (and computers in general) you have two types of operations: numerical and bit operations. Since you want to avoid the latter, you have to use the former.

Luckily there's a simple association between bits and numbers. Bits in an integer correspond to powers of two. The lowest bit represents 2^0=1, the next one 2^1=2 etcetera.

We need to start with the highest power of two:

int p2 = (INT_MAX - INT_MAX/2);

and then copy every set bit over:

int result = 0
while (p2 > 0)
{
    if (a>p2) // This bit is set in a2, copy it.
    {
         result += p2;
         a -= p2;
    }
    p2 /= 2;
}

except when p2 is the bit you want to set, of course. I'll leave that part of the exercise to you.

You can try a macro like this

#define SET_BIT(data, bit) (data) |= 1 << (bit);    

Usage

int num = 0;
SET_BIT(num, 2);    // num = 4

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM