如果设置了另一个位,则清除位
Clear bit if another is set
是否有类似于:if((bitmap & BIT_WATER) && (bitmap & BIT_FIRE)) bitmap &= ~BIT_FIRE
或
if(bitmap & BIT_WATER) bitmap &= ~BIT_FIRE
在仅使用按位运算的单个语句中,无需比较 (if)?
我的意思是,如果两个旗帜,每个旗帜都与另一个完全相反,被明确设置其中一个。
一种情况下,您可以避免bitmap & BIT_FIRE
,因为如果未设置BIT_FIRE
bitmap &= ~BIT_FIRE;
则不会对bitmap
执行任何操作。
没有任意方式的"如果设置了位 Y,则设置位 X"。
当然,如果你知道,比如说,BIT_FIRE
比BIT_WATER
高一点,你可以做bitmap &= ~(BIT_WATER << 1)
,这将清除"比BIT_WATER
高一点"。
可能过早优化,但你可以这样做
bitmap &= ~((bitmap & BIT_WATER) * (BIT_FIRE/BIT_WATER)) & ~((bitmap & BIT_WATER) * (BIT_WATER/BIT_FIRE))
只要BIT_FIRE和BIT_WATER是单比特(2的幂)。 您可能还希望位图是无符号的,以确保编译器可以轻松地将其优化为单个移位、两个按位 and 和一个补码。
当然,一个好的编译器会优化你的原始代码,直到相同的 4 条指令,没有分支。
编辑
当然,我意识到上述内容是不正确的 - 只有在BIT_FIRE> BIT_WATER时才有效。
所以只要坚持原来的if,让编译器优化它......
将我的评论提升为答案。请注意,它使用乘法,但也许它仍然对您有用(ideone.com 上的代码):
#include <iostream>
int main()
{
int long unsigned bitmap_with_water = 0xF300003F;
int long unsigned bitmap_without_water = 0xF300000F;
int long unsigned bit_fire = 0x03000000;
int long unsigned bit_water = 0x00000030;
bitmap_with_water &= ~(bit_fire * static_cast<bool>(bitmap_with_water & bit_water));
bitmap_without_water &= ~(bit_fire * static_cast<bool>(bitmap_without_water & bit_water));
std::cout << (void*)(bitmap_with_water) << "t" << (void*)(bitmap_without_water) << std::endl;
return (0);
}
程序输出:
0xf000003f 0xf300000f
如果你需要写一个通用的clear_if_set(int test, int clear, int bitmap)
那么这个答案是没有用的。
如果这是一个专门的功能,并且您知道从火到水的转换距离:
int water = bitmap & BIT_WATER;
int shifted = water << WATER_TO_FIRE_LSHIFT; // for example
bitmap &= ~shifted;
单行:
bitmap &= ~((bitmap & BIT_WATER) << WATER_TO_FIRE_LSHIFT);
如果使用位号而不是预移位掩码是可以接受的:
bitmap &= ~(((bitmap >> SHIFT_WATER) & 1) << SHIFT_FIRE)
假设BIT_WATER和BIT_FIRE不是同一个位,那么
的真值表
if(bitmap & BIT_WATER) bitmap &= ~BIT_FIRE
是(BIT_WATER、旧BIT_FIRE、新BIT_FIRE)
0 0 0
0 1 1
1 0 0
1 1 0
所以从一点的角度来看,这是
BIT_FIRE = (~BIT_WATER)&BIT_FIRE;
1 0 0
1 1 1
0 0 0
0 1 0
由于我不知道您的两个位之间的差距,因此这样的事情太过分了。
newbit = ((~(bitmap>>BIT_WATER_BIT))&(bitmap>>BIT_FIRE_BIT))&1;
bitmap&=~BIT_FIRE;
bitmap|=newbit<<BIT_FIRE_BIT;
假设我没有打错字...此外,如果您利用特定的位号并且不做一些通用的事情(将BIT_WATER位移位以降落在BIT_FIRE而不是将所有内容向右然后再次向左移动,我认为可以简化。 不过可能不会让它更简单。
如果位水位为 7,位火位为 3
bitmap = (((~(bitmap>>4))>>4)&(1<<3))&bitmap;
或者也许这个
bitmap = (((bitmap&(~BIT_WATER))^BIT_WATER)>>4)&bitmap;
其中>>4 是 BIT_WATER 和BIT_FIRE之间的方向和增量。 填写正确的增量。
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 运行同一解决方案的另一个项目的项目
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- C++从另一个类访问公共静态向量的正确方法是什么
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- 使用std::transform将一个范围的元素添加到另一个范围中
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 修改函数中的指针(将另一个指针作为参数传递)
- 为什么我不能将一个对象push_back到属于另一个类的对象向量中?
- C++试图读取一个文件并输出到另一个文本文件
- 如何将指针从一个void函数传递到另一个C++
- 如何从另一个文件继承私有成员变量和公共函数
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- C++-我可以创建另一个类的成员并在构造函数中使用它吗
- 如何在C++中将函数发送到另一个进程
- 清除向量并让一个向量等于另一个向量