如何在C / C ++中设置,清除和切换?
答案 0 :(得分:3313)
使用按位OR运算符(|
)来设置位。
number |= 1UL << n;
这将设置n
的{{1}}位。 number
应为零,如果要设置n
st位,依此类推至1
,如果要设置n-1
位。
如果n
宽于1ULL
,请使用number
;在unsigned long
评估1UL << n
未定义的行为超过1UL << n
的宽度之后,long
的推广才会发生。这同样适用于所有其他示例。
使用按位AND运算符(&
)清除一点。
number &= ~(1UL << n);
这将清除n
的{{1}}位。必须使用按位NOT运算符(number
)反转位串,然后运行AND。
XOR运算符(~
)可用于切换位。
^
这将切换number ^= 1UL << n;
的{{1}}位。
你没有要求这个,但我不妨加上它。
要检查一下,将数字n向右移动,然后按位向右移动:
n
这会将number
bit = (number >> n) & 1U;
的值放入变量n
。
将number
位设置为bit
或n
可以通过以下2的补码C ++实现来实现:
1
如果0
为number ^= (-x ^ number) & (1UL << n);
,则会设置位n
,如果x
为1
,则会将其清除。如果x
有其他值,则会产生垃圾。 0
会将其booleanize为0或1。
为了使其独立于2的补码否定行为(其中x
设置了所有位,与1的补码或符号/幅度C ++实现不同),使用无符号否定。
x = !!x
或
-1
使用无符号类型进行便携式位操作通常是个好主意。
或
number ^= (-(unsigned long)x ^ number) & (1UL << n);
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
将清除number = (number & ~(1UL << n)) | (x << n);
位,(number & ~(1UL << n))
会将n
位设置为(x << n)
。
一般来说,通常不要复制/粘贴代码也是一个好主意,所以很多人都使用预处理器宏(如the community wiki answer further down)或某种封装。
答案 1 :(得分:427)
使用标准C ++库:std::bitset<N>
。
或Boost版本:boost::dynamic_bitset
。
无需自行推送:
#include <bitset>
#include <iostream>
int main()
{
std::bitset<5> x;
x[1] = 1;
x[2] = 0;
// Note x[0-4] valid
std::cout << x << std::endl;
}
[Alpha:] > ./a.out
00010
Boost版本允许运行时大小的bitset与standard library编译时大小的bitset进行比较。
答案 2 :(得分:224)
另一种选择是使用位字段:
struct bits {
unsigned int a:1;
unsigned int b:1;
unsigned int c:1;
};
struct bits mybits;
定义了一个3位字段(实际上,它是三个1位字符)。位操作现在变得有点(哈哈)更简单:
设置或清除一下:
mybits.b = 1;
mybits.c = 0;
要切换一下:
mybits.a = !mybits.a;
mybits.b = ~mybits.b;
mybits.c ^= 1; /* all work */
检查一下:
if (mybits.c) //if mybits.c is non zero the next line below will execute
这仅适用于固定大小的位字段。否则你必须采用以前帖子中描述的比特笨拙的技术。
答案 3 :(得分:154)
我使用头文件中定义的宏来处理位集和清除:
/* a=target variable, b=bit number to act upon 0-n */
#define BIT_SET(a,b) ((a) |= (1ULL<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1ULL<<(b)))
#define BIT_FLIP(a,b) ((a) ^= (1ULL<<(b)))
#define BIT_CHECK(a,b) (!!((a) & (1ULL<<(b)))) // '!!' to make sure this returns 0 or 1
/* x=target variable, y=mask */
#define BITMASK_SET(x,y) ((x) |= (y))
#define BITMASK_CLEAR(x,y) ((x) &= (~(y)))
#define BITMASK_FLIP(x,y) ((x) ^= (y))
#define BITMASK_CHECK_ALL(x,y) (((x) & (y)) == (y)) // warning: evaluates y twice
#define BITMASK_CHECK_ANY(x,y) ((x) & (y))
答案 4 :(得分:111)
有时值得使用enum
名称位:
enum ThingFlags = {
ThingMask = 0x0000,
ThingFlag0 = 1 << 0,
ThingFlag1 = 1 << 1,
ThingError = 1 << 8,
}
然后使用名称。即写
thingstate |= ThingFlag1;
thingstate &= ~ThingFlag0;
if (thing & ThingError) {...}
设置,清除和测试。这样您就可以隐藏其余代码中的幻数。
除此之外,我赞同杰里米的解决方案。
答案 5 :(得分:41)
/*
** Bit set, clear, and test operations
**
** public domain snippet by Bob Stout
*/
typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL;
#define BOOL(x) (!(!(x)))
#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))
好的,让我们分析一下......
您似乎在所有这些问题中遇到问题的常见表达是“(1L&lt;&lt;(posn))”。所有这一切都是创建一个单一位的掩码 哪个适用于任何整数类型。 “posn”参数指定了 你想要的位置。如果posn == 0,那么这个表达式会 评估:
0000 0000 0000 0000 0000 0000 0000 0001 binary.
如果posn == 8,它将评估为
0000 0000 0000 0000 0000 0001 0000 0000 binary.
换句话说,它只是创建一个0的字段,在指定的位置为1 位置。唯一棘手的部分是我们需要设置的BitClr()宏 在1的字段中的单个0位。这是通过使用1来完成的 由波浪号(〜)运算符表示的相同表达式的补码。
创建蒙版后,它就像你建议的那样应用于参数, 通过使用按位和(&amp;),或(|)和xor(^)运算符。自面具 类型为long,宏也可以在char,short,int上工作, 或长的。
最重要的是,这是对整个班级的一般解决方案 问题。当然,重写它是可能的,甚至是适当的 每当您使用显式掩码值时,相当于任何这些宏 需要一个,但为什么呢?请记住,宏替换发生在 预处理器等生成的代码将反映出值的事实 编译器认为它是恒定的 - 即使用它同样有效 每次你需要做的“重新发明轮子”的通用宏 位操纵。
服气?这是一些测试代码 - 我使用Watcom C进行全面优化 并且不使用_cdecl,因此生成的反汇编将像干净一样 可能的:
---- [TEST.C] -------------------------------------- --------------------------
#define BOOL(x) (!(!(x)))
#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))
int bitmanip(int word)
{
word = BitSet(word, 2);
word = BitSet(word, 7);
word = BitClr(word, 3);
word = BitFlp(word, 9);
return word;
}
---- [TEST.OUT(disassembled)] ----------------------------------- ------------
Module: C:\BINK\tst.c
Group: 'DGROUP' CONST,CONST2,_DATA,_BSS
Segment: _TEXT BYTE 00000008 bytes
0000 0c 84 bitmanip_ or al,84H ; set bits 2 and 7
0002 80 f4 02 xor ah,02H ; flip bit 9 of EAX (bit 1 of AH)
0005 24 f7 and al,0f7H
0007 c3 ret
No disassembly errors
---- [finis] ---------------------------------------- -------------------------
答案 6 :(得分:34)
使用按位运算符:&
|
设置000b
中的最后一位:
foo = foo | 001b
检查foo
中的最后一位:
if ( foo & 001b ) ....
清除foo
中的最后一位:
foo = foo & 110b
为了清楚起见,我使用了XXXb
。您可能正在使用HEX表示,具体取决于您打包位的数据结构。
答案 7 :(得分:31)
对于初学者,我想用一个例子来解释一下:
示例:
value is 0x55;
bitnum : 3rd.
使用&
运算符检查位:
0101 0101
&
0000 1000
___________
0000 0000 (mean 0: False). It will work fine if the third bit is 1 (then the answer will be True)
切换或翻转:
0101 0101
^
0000 1000
___________
0101 1101 (Flip the third bit without affecting other bits)
|
运算符:设置位
0101 0101
|
0000 1000
___________
0101 1101 (set the third bit without affecting other bits)
答案 8 :(得分:25)
这是我最喜欢的位算术宏,适用于从unsigned char
到size_t
的任何类型的无符号整数数组(这是应该有效处理的最大类型):
#define BITOP(a,b,op) \
((a)[(size_t)(b)/(8*sizeof *(a))] op ((size_t)1<<((size_t)(b)%(8*sizeof *(a)))))
设置位:
BITOP(array, bit, |=);
要清楚一点:
BITOP(array, bit, &=~);
要切换一下:
BITOP(array, bit, ^=);
测试一下:
if (BITOP(array, bit, &)) ...
等
答案 9 :(得分:23)
由于这被标记为“嵌入式”,我假设你正在使用微控制器。以上所有建议均有效且有效。工作(读 - 修改 - 写,工会,结构等)。
然而,在基于示波器的调试回合中,我惊讶地发现,与直接将值写入微型PORTnSET / PORTnCLEAR寄存器相比,这些方法在CPU周期中具有相当大的开销,这使得存在紧张循环/高频ISR的切换引脚。
对于那些不熟悉的人:在我的例子中,micro有一个通用的引脚状态寄存器PORTn,它反映了输出引脚,所以做PORTn | = BIT_TO_SET会导致对该寄存器的读 - 修改 - 写。但是,PORTnSET / PORTnCLEAR寄存器取“1”表示“请将此位1”(SET)或“请将此位置零”(CLEAR),将“0”表示“保持引脚单独”。因此,您最终会得到两个端口地址,具体取决于您是设置还是清除该位(并非总是方便),而是很多更快的反应和更小的汇编代码。
答案 10 :(得分:23)
位域方法在嵌入式领域具有其他优势。您可以定义一个直接映射到特定硬件寄存器中的位的结构。
struct HwRegister {
unsigned int errorFlag:1; // one-bit flag field
unsigned int Mode:3; // three-bit mode field
unsigned int StatusCode:4; // four-bit status code
};
struct HwRegister CR3342_AReg;
您需要了解位打包顺序 - 我认为它首先是MSB,但这可能与实现有关。另外,验证编译器处理程序如何跨越字节边界。
然后,您可以像以前一样阅读,编写,测试各个值。
答案 11 :(得分:19)
更一般地说,对于任意大小的位图:
#define BITS 8
#define BIT_SET( p, n) (p[(n)/BITS] |= (0x80>>((n)%BITS)))
#define BIT_CLEAR(p, n) (p[(n)/BITS] &= ~(0x80>>((n)%BITS)))
#define BIT_ISSET(p, n) (p[(n)/BITS] & (0x80>>((n)%BITS)))
答案 12 :(得分:18)
#define bit_test(x, y) ( ( ((const char*)&(x))[(y)>>3] & 0x80 >> ((y)&0x07)) >> (7-((y)&0x07) ) )
样本使用:
int main(void)
{
unsigned char arr[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
for (int ix = 0; ix < 64; ++ix)
printf("bit %d is %d\n", ix, bit_test(arr, ix));
return 0;
}
备注:强> 这是为了快速(具有灵活性)和非分支。在编译Sun Studio 8时,它可以生成高效的SPARC机器代码;我还在amd64上使用MSVC ++ 2008测试了它。可以制作类似的宏来设置和清除位。与其他许多解决方案相比,此解决方案的主要区别在于它适用于任何类型的变量中的任何位置。
答案 13 :(得分:13)
该程序将任何数据位从0更改为1或1更改为0:
{
unsigned int data = 0x000000F0;
int bitpos = 4;
int bitvalue = 1;
unsigned int bit = data;
bit = (bit>>bitpos)&0x00000001;
int invbitvalue = 0x00000001&(~bitvalue);
printf("%x\n",bit);
if (bitvalue == 0)
{
if (bit == 0)
printf("%x\n", data);
else
{
data = (data^(invbitvalue<<bitpos));
printf("%x\n", data);
}
}
else
{
if (bit == 1)
printf("elseif %x\n", data);
else
{
data = (data|(bitvalue<<bitpos));
printf("else %x\n", data);
}
}
}
答案 14 :(得分:13)
如果你做了很多事情,你可能想要使用面具,这将使整个事情变得更快。以下函数非常快且仍然灵活(它们允许在任何大小的位图中进行位错)。
const unsigned char TQuickByteMask[8] =
{
0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80,
};
/** Set bit in any sized bit mask.
*
* @return none
*
* @param bit - Bit number.
* @param bitmap - Pointer to bitmap.
*/
void TSetBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] |= TQuickByteMask[n]; // Set bit.
}
/** Reset bit in any sized mask.
*
* @return None
*
* @param bit - Bit number.
* @param bitmap - Pointer to bitmap.
*/
void TResetBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] &= (~TQuickByteMask[n]); // Reset bit.
}
/** Toggle bit in any sized bit mask.
*
* @return none
*
* @param bit - Bit number.
* @param bitmap - Pointer to bitmap.
*/
void TToggleBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] ^= TQuickByteMask[n]; // Toggle bit.
}
/** Checks specified bit.
*
* @return 1 if bit set else 0.
*
* @param bit - Bit number.
* @param bitmap - Pointer to bitmap.
*/
short TIsBitSet( short bit, const unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
// Test bit (logigal AND).
if (bitmap[x] & TQuickByteMask[n])
return 1;
return 0;
}
/** Checks specified bit.
*
* @return 1 if bit reset else 0.
*
* @param bit - Bit number.
* @param bitmap - Pointer to bitmap.
*/
short TIsBitReset( short bit, const unsigned char *bitmap)
{
return TIsBitSet(bit, bitmap) ^ 1;
}
/** Count number of bits set in a bitmap.
*
* @return Number of bits set.
*
* @param bitmap - Pointer to bitmap.
* @param size - Bitmap size (in bits).
*
* @note Not very efficient in terms of execution speed. If you are doing
* some computationally intense stuff you may need a more complex
* implementation which would be faster (especially for big bitmaps).
* See (http://graphics.stanford.edu/~seander/bithacks.html).
*/
int TCountBits( const unsigned char *bitmap, int size)
{
int i, count = 0;
for (i=0; i<size; i++)
if (TIsBitSet(i, bitmap))
count++;
return count;
}
注意,要在16位整数中设置位'n',请执行以下操作:
TSetBit( n, &my_int);
由您来确保位数在您传递的位图范围内。请注意,对于小字节,处理器,字节,字,双字,qword等,在内存中正确映射(小端处理器比大端处理器“更好”的主要原因啊,我觉得火焰战即将到来上...)。
答案 15 :(得分:11)
使用此:
int ToggleNthBit ( unsigned char n, int num )
{
if(num & (1 << n))
num &= ~(1 << n);
else
num |= (1 << n);
return num;
}
答案 16 :(得分:10)
如果你想在 Linux内核中使用C编程执行所有操作,那么我建议使用Linux内核的标准API。
请参阅https://www.kernel.org/doc/htmldocs/kernel-api/ch02s03.html
set_bit Atomically set a bit in memory
clear_bit Clears a bit in memory
change_bit Toggle a bit in memory
test_and_set_bit Set a bit and return its old value
test_and_clear_bit Clear a bit and return its old value
test_and_change_bit Change a bit and return its old value
test_bit Determine whether a bit is set
注意:这里整个操作只需一步即可完成。因此,即使在SMP计算机上,所有这些都保证原子并且非常有用 保持处理器之间的一致性。
答案 17 :(得分:10)
扩展bitset
答案:
#include <iostream>
#include <bitset>
#include <string>
using namespace std;
int main() {
bitset<8> byte(std::string("10010011");
// Set Bit
byte.set(3); // 10010111
// Clear Bit
byte.reset(2); // 10010101
// Toggle Bit
byte.flip(7); // 00010101
cout << byte << endl;
return 0;
}
答案 18 :(得分:9)
Visual C 2010,也许还有许多其他编译器,都直接支持内置的位操作。令人惊讶的是,即使sizeof()运算符也能正常工作。
bool IsGph[256], IsNotGph[256];
// Initialize boolean array to detect printable characters
for(i=0; i<sizeof(IsGph); i++) {
IsGph[i] = isgraph((unsigned char)i);
}
所以,对于你的问题,IsGph [i] = 1,或IsGph [i] = 0使设置和清除bool变得容易。
找到不可打印的字符......
// Initialize boolean array to detect UN-printable characters,
// then call function to toggle required bits true, while initializing a 2nd
// boolean array as the complement of the 1st.
for(i=0; i<sizeof(IsGph); i++) {
if(IsGph[i]) {
IsNotGph[i] = 0;
} else {
IsNotGph[i] = 1;
}
}
请注意,此代码没有“特殊”。它有点像整数 - 在技术上,它是。 1位整数,可以容纳2个值,仅包含2个值。
我曾经使用这种方法查找重复的贷款记录,其中loan_number是ISAM密钥,使用6位贷款编号作为位数组的索引。野蛮的快速,并在8个月后,证明我们从中获取数据的主机系统实际上是故障。比特阵列的简单性使得它们的正确性非常高 - 例如,与搜索方法相比。
答案 19 :(得分:6)
使用其中一个定义为here的运算符。
要设置位,请使用int x = x | 0x?;
,其中?
是二进制形式的位位置。
答案 20 :(得分:5)
以下是我使用的一些宏:
SET_FLAG(Status, Flag) ((Status) |= (Flag))
CLEAR_FLAG(Status, Flag) ((Status) &= ~(Flag))
INVALID_FLAGS(ulFlags, ulAllowed) ((ulFlags) & ~(ulAllowed))
TEST_FLAGS(t,ulMask, ulBit) (((t)&(ulMask)) == (ulBit))
IS_FLAG_SET(t,ulMask) TEST_FLAGS(t,ulMask,ulMask)
IS_FLAG_CLEAR(t,ulMask) TEST_FLAGS(t,ulMask,0)
答案 21 :(得分:5)
使用的变量
int value, pos;
值-数据
pos-我们想要设置,清除或切换的位的位置
设置一些
value = value | 1 << pos;
清除
value = value & ~(1 << pos);
切换一下
value = value ^ 1 << pos;
答案 22 :(得分:4)
如何设置,清除和切换一个位?
解决在尝试形成面具时常见的编码陷阱:
1
并不总是足够宽
当number
类型比1
更广泛时,会出现什么问题?
对于导致未定义行为(UB)的转换x
,1 << x
可能太大了。即使x
不是太大,~
也可能无法翻转最重要的位。
// assume 32 bit int/unsigned
unsigned long long number = foo();
unsigned x = 40;
number |= (1 << x); // UB
number ^= (1 << x); // UB
number &= ~(1 << x); // UB
x = 10;
number &= ~(1 << x); // Wrong mask, not wide enough
确保1足够宽:
代码可以使用1ull
或迂腐(uintmax_t)1
并让编译器进行优化。
number |= (1ull << x);
number |= ((uintmax_t)1 << x);
或演员表 - 这会使编码/审核/维护问题保持正确和最新。
number |= (type_of_number)1 << x;
或者通过强制进行至少与1
类型一样宽的数学运算来轻轻推广number
。
number |= (number*0 + 1) << x;
与大多数位操作一样,最好使用 unsigned 类型而不是签名类型
答案 23 :(得分:4)
int set_nth_bit(int num, int n){
return (num | 1 << n);
}
int clear_nth_bit(int num, int n){
return (num & ~( 1 << n));
}
int toggle_nth_bit(int num, int n){
return num ^ (1 << n);
}
int check_nth_bit(int num, int n){
return num & (1 << n);
}
答案 24 :(得分:3)
C ++ 11模板化版本(放在标题中):
namespace bit {
template <typename T1, typename T2> inline void set (T1 &variable, T2 bit) {variable |= ((T1)1 << bit);}
template <typename T1, typename T2> inline void clear(T1 &variable, T2 bit) {variable &= ~((T1)1 << bit);}
template <typename T1, typename T2> inline void flip (T1 &variable, T2 bit) {variable ^= ((T1)1 << bit);}
template <typename T1, typename T2> inline bool test (T1 &variable, T2 bit) {return variable & ((T1)1 << bit);}
}
namespace bitmask {
template <typename T1, typename T2> inline void set (T1 &variable, T2 bits) {variable |= bits;}
template <typename T1, typename T2> inline void clear(T1 &variable, T2 bits) {variable &= ~bits;}
template <typename T1, typename T2> inline void flip (T1 &variable, T2 bits) {variable ^= bits;}
template <typename T1, typename T2> inline bool test_all(T1 &variable, T2 bits) {return ((variable & bits) == bits);}
template <typename T1, typename T2> inline bool test_any(T1 &variable, T2 bits) {return variable & bits;}
}
答案 25 :(得分:1)
首先假设几件事
num = 55
整数,用于执行按位运算(设置,获取,清除,切换)。
n = 4
基于0的位位置以执行按位运算。
nth
num个右移num
的次数,n
次。然后与1进行按位与&
。bit = (num >> n) & 1;
它如何工作?
0011 0111 (55 in decimal)
>> 4 (right shift 4 times)
-----------------
0000 0011
& 0000 0001 (1 in decimal)
-----------------
=> 0000 0001 (final result)
n
次。然后对|
执行按位或num
操作。num |= (1 << n); // Equivalent to; num = (1 << n) | num;
它如何工作?
0000 0001 (1 in decimal)
<< 4 (left shift 4 times)
-----------------
0001 0000
| 0011 0111 (55 in decimal)
-----------------
=> 0001 0000 (final result)
n
次,即1 << n
。~ (1 << n)
。&
执行按位与num
运算。以上三个步骤可以写成num & (~ (1 << n))
; num &= (~(1 << n)); // Equivalent to; num = num & (~(1 << n));
它如何工作?
0000 0001 (1 in decimal)
<< 4 (left shift 4 times)
-----------------
~ 0001 0000
-----------------
1110 1111
& 0011 0111 (55 in decimal)
-----------------
=> 0010 0111 (final result)
要切换一点,我们使用按位XOR ^
运算符。如果两个操作数的对应位不同,则按位XOR运算符的结果为1,否则为0。
这意味着要切换一位,我们需要对要切换的位和1执行XOR操作。
num ^= (1 << n); // Equivalent to; num = num ^ (1 << n);
它如何工作?
0 ^ 1 => 1
。 1 ^ 1 => 0
。 0000 0001 (1 in decimal)
<< 4 (left shift 4 times)
-----------------
0001 0000
^ 0011 0111 (55 in decimal)
-----------------
=> 0010 0111 (final result)
答案 26 :(得分:1)
该程序基于@Jeremy的上述解决方案。如果有人希望快速游玩。
constexpr auto rotate_left(orientation o) -> orientation {
return rotate(o, -1);
}
constexpr auto rotate_right(orientation o) -> orientation {
return rotate(o, 1);
}
答案 27 :(得分:1)
在Java中,使用BitSet(java.util.BitSet
)类可能会有所帮助。
它还具有经常需要的方法。当需要位处理且没有上限时,使用BitSet可以证明是一个不错的选择。
将数字用作BitSet的对象。
你可以,
number.set(indexOfTargetedBit)
number.clear(indexOfTargetedBit)
number.flip(indexOfTargetedBit)
您可以获得有关BitSet here
的更多此类详细信息答案 28 :(得分:0)
有时当您不确定 -1 或类似的结果会导致什么时,您可能希望设置第 n 位而不使用 -1:
number = (((number | (1 << n)) ^ (1 << n))) | (x << n);
说明:((number | (1 << n)
将第 n 位设置为 1(其中 |
表示按位或),然后使用 (...) ^ (1 << n)
我们将第 n 位设置为 0,最后使用 {{1}我们将第 n 位设为 0,设置为(位值)(...) | x << n)
。
这也适用于 x
。
答案 29 :(得分:0)
这是一个用 C 语言执行基本按位运算的例程:
#define INT_BIT (unsigned int) (sizeof(unsigned int) * 8U) //number of bits in unsigned int
int main(void)
{
unsigned int k = 5; //k is the bit position; here it is the 5th bit from the LSb (0th bit)
unsigned int regA = 0x00007C7C; //we perform bitwise operations on regA
regA |= (1U << k); //Set kth bit
regA &= ~(1U << k); //Clear kth bit
regA ^= (1U << k); //Toggle kth bit
regA = (regA << k) | regA >> (INT_BIT - k); //Rotate left by k bits
regA = (regA >> k) | regA << (INT_BIT - k); //Rotate right by k bits
return 0;
}
答案 30 :(得分:-1)
您始终可以在代码中定义位。然后使用OR设置所需的位,并使用AND&Negate重置该位。 请在此处找到建议的答案:https://stackoverflow.com/a/47056742/2837780
答案 31 :(得分:-2)
在C语言中尝试使用其中一个函数来改变n位:
char bitfield;
// Start at 0th position
void chang_n_bit(int n, int value)
{
bitfield = (bitfield | (1 << n)) & (~( (1 << n) ^ (value << n) ));
}
或者
void chang_n_bit(int n, int value)
{
bitfield = (bitfield | (1 << n)) & ((value << n) | ((~0) ^ (1 << n)));
}
或者
void chang_n_bit(int n, int value)
{
if(value)
bitfield |= 1 << n;
else
bitfield &= ~0 ^ (1 << n);
}
char get_n_bit(int n)
{
return (bitfield & (1 << n)) ? 1 : 0;
}
答案 32 :(得分:-2)
设置位16的示例。
#include <stdio.h>
#define SET_BIT_NUMBER 16
int main() {
unsigned int dataWord = 0;
dataWord |= (1 << SET_BIT_NUMBER);
printf("dataWord (hex): %x\n", dataWord);
return 0;
}