c++ - 有效地从 32 位数据类型中删除 2 位
问题描述
假设您有 32 位数据类型:
// The letters are just to identify the position of each bit later in the post
abcdefgh ijklmnop qrstuvwx yzABCDEF
我正在记录在某些位置“丢弃”位的最有效方法,其中丢弃意味着“删除”给定位,并移动以下位以填充其位置。
示例:假设我想删除位“a”和“q”。然后结果应该看起来像:
bcdefghi jklmnopr stuvwxyz ABCDEF00
或者
00bcdefg hijklmno prstuvwx yzABCDEF
任何一个结果都是可以接受的。
在我的具体情况下,我还可以施加以下约束:
- 在我的情况下,下降的位置是静态的;即我总是需要准确地删除第 1 位和第 16 位(“a”和“q”)
- 要删除的位(“a”和“q”)始终为 0
- 最终填充数据的位(操作后向左或向右的“00”)无关紧要 - 即,它们实际上是 0 还是 1 无关紧要
目前我正在使用这样的方法(伪代码):
// called with number = abcdefgh ijklmnop qrstuvwx yzABCDEF
auto drop_bits_1_16(unsigned int number)
{
number = number << 1; // number becomes: bcdefghi jklmnopq rstuvwxy zABCDEF0
unsigned number1 = number & 0xFFFE0000; // number1 comes: bcdefghi jklmnop0 00000000 00000000
unsigned number2 = number & 0x0000FFFF; // number2 becomes: 00000000 00000000 rstuvwxy zABCDEF0
number2 = number2 << 1; // number2 becomes: 00000000 0000000r stuvwxyz ABCDEF00
return number1 | number2; // returns bcdefghi jklmnopr stuvwxyz ABCDEF00
}
但我想知道那里是否有更聪明/更有效的方法?
解决方案
向右打包比向左打包要容易一些,因为只需要移动 15 位,而不是 15 的两倍。我不知道如何取消屏蔽,所以
((number & 0x7FFF0000) >> 1) | (number & 0x00007FFF)
这不需要丢弃的位为零。有四次按位运算,越少就会困难。
三个操作有一个方法!
添加 15 个低位以将它们左移一位(乘以 2),然后将整体右移。
(number + (number & 0x7FFF)) >> 1
注意:第 15 位必须为零。
也许下面的表达式会给编译器一些更好的代码生成选项:
(number + (unsigned short)number) >> 1
我应该补充一点,其他最终布局也是可能的吗?
(number + (unsigned short)number) << 1
推荐阅读
- python - Python中两列的虚拟变量
- firebase - 无法显示 Firebase 数据以显示在简单的 Vue 应用程序上
- sql - 我可以使用子查询动态选择变体键,而无需展平表吗?
- ios - 在 iOS 上观察 MIDI 设备连接通知
- python - 如何使用pymsql参数化sql查询
- python - 没有足够的值来解压 ValueError,如何在 Spyder 中为 sys.stdin.read() 修复它
- r - 如何根据所在组的大小为项目添加权重
- vim - 如何在 WSL 中从 Vim 复制/粘贴
- node.js - MongoDB 中的视频文件
- sonarqube - SonarQube v8.2 错误:扫描简单 .net 代码时(javax.xml.parsers.SAXParserFactory 等...)