从 uint32 获取特定位
Get specific bit from uint32
我有一个 UInt32
变量,例如 3238844000。
现在我想得到这个数的前两位和前两位之后的6位。两个位都应该是 int。
Decimal: 3238844000
Binary: 11000001000011001101011001100000
^^
和
Decimal: 3238844000
Binary: 11000001000011001101011001100000
^^^^^^
更新二:
这种情况下的最简单(也是最快)的方法是纯粹 使用 bitwise-shift 运算符
int val = (int)(input >> 30); // performs the same
int val2 = (int)((input << 2) >> 26); //the simplest and the fastest way
我之前听说 bitwise-shift 操作往往会更快。但是今天,出于好奇*,我真的比较了 bitwise-shift + mask ((int)((input & mask2) >> 24)
) 和单独 bitwise-shift ((int)((input << 2) >> 26)
) 之间的性能。 bitwise-shift 单独操作大约 快 10%-15%。
这是我得到的结果:
[2016-01-20 04:01:26.638 UTC] shift-mask: 235 ms shift-only: 199 ms
[2016-01-20 04:01:30.402 UTC] shift-mask: 233 ms shift-only: 200 ms
[2016-01-20 04:01:31.265 UTC] shift-mask: 233 ms shift-only: 198 ms
[2016-01-20 04:01:32.116 UTC] shift-mask: 227 ms shift-only: 199 ms
[2016-01-20 04:01:32.850 UTC] shift-mask: 233 ms shift-only: 198 ms
[2016-01-20 04:01:33.584 UTC] shift-mask: 230 ms shift-only: 199 ms
[2016-01-20 04:01:34.280 UTC] shift-mask: 263 ms shift-only: 214 ms
[2016-01-20 04:01:35.055 UTC] shift-mask: 229 ms shift-only: 201 ms
[2016-01-20 04:01:36.996 UTC] shift-mask: 234 ms shift-only: 201 ms
[2016-01-20 04:01:37.933 UTC] shift-mask: 224 ms shift-only: 198 ms
[2016-01-20 04:01:38.353 UTC] shift-mask: 222 ms shift-only: 196 ms
[2016-01-20 04:01:38.798 UTC] shift-mask: 233 ms shift-only: 211 ms
[2016-01-20 04:01:39.246 UTC] shift-mask: 235 ms shift-only: 213 ms
[2016-01-20 04:01:39.668 UTC] shift-mask: 223 ms shift-only: 198 ms
[2016-01-20 04:01:41.102 UTC] shift-mask: 234 ms shift-only: 200 ms
[2016-01-20 04:01:41.524 UTC] shift-mask: 224 ms shift-only: 198 ms
[2016-01-20 04:01:41.948 UTC] shift-mask: 223 ms shift-only: 200 ms
[2016-01-20 04:01:42.373 UTC] shift-mask: 224 ms shift-only: 200 ms
[2016-01-20 04:01:43.521 UTC] shift-mask: 233 ms shift-only: 197 ms
[2016-01-20 04:01:44.272 UTC] shift-mask: 237 ms shift-only: 216 ms
[2016-01-20 04:01:44.909 UTC] shift-mask: 231 ms shift-only: 196 ms
[2016-01-20 04:01:45.353 UTC] shift-mask: 230 ms shift-only: 213 ms
[2016-01-20 04:01:45.850 UTC] shift-mask: 237 ms shift-only: 207 ms
[2016-01-20 04:01:46.276 UTC] shift-mask: 226 ms shift-only: 200 ms
[2016-01-20 04:01:47.074 UTC] shift-mask: 234 ms shift-only: 203 ms
[2016-01-20 04:01:47.718 UTC] shift-mask: 230 ms shift-only: 199 ms
[2016-01-20 04:01:48.144 UTC] shift-mask: 226 ms shift-only: 200 ms
[2016-01-20 04:01:48.567 UTC] shift-mask: 225 ms shift-only: 198 ms
[2016-01-20 04:01:48.994 UTC] shift-mask: 225 ms shift-only: 199 ms
[2016-01-20 04:01:49.429 UTC] shift-mask: 223 ms shift-only: 211 ms
[2016-01-20 04:01:49.860 UTC] shift-mask: 232 ms shift-only: 198 ms
[2016-01-20 04:01:50.284 UTC] shift-mask: 225 ms shift-only: 199 ms
注意:每个实验完成 (5,000,000 x 100) 次操作。
*记得我过去与 micro-controllers 打交道的日子……;)
原文:
就像您如何找到 UInt32
的二进制表示一样,您应该在其 二进制表示[=81= 中找到正确的 位掩码 ] 也是:
uint mask1 = 0xC0000000; //1100 0000 0000 0000 0000 0000 0000 0000
uint mask2 = 0x3F000000; //0011 1111 0000 0000 0000 0000 0000 0000
然后将它们与 bitwise-and operator
一起使用
要获得前两位,您可以像这样简单地使用掩码:
uint val = input & mask1; //should give you the first two bits, the rests are zero
并获取接下来的 6 位:
uint val2 = input & mask2; //similarly, should give you only the six bits in the position which you want
如果你在 int
中需要它们,那么简单地转换它们:
int val = (int)(input & mask1);
int val2 = (int)(input & mask2);
如果你想把结果放在 LSB 中(最低位 byte
,最右边 8-bit
在这种情况下),使用 按位右移 运算符:
int val = (int)((input & mask1) >> 30); //30 bits are 0
int val2 = (int)((input & mask2) >> 24); //24 bits are 0
更新:
至于上面的移位版本,实际上,你也可以简单地按位右移第一个,对第二个做几乎类似的操作,除了它需要一个0x3F
(0011 1111
) 的按位掩码 以清除不需要的前两位。
int val = (int)(input >> 30); // performs the same
int val2 = (int)((input >> 24) & 0x3F); //the simpler way
他们在bit-representation中发生的事情如下(我给出评论是为了简化逻辑流程):
The first one:
1100 0001 0000 1100 1101 0110 0110 0000
--------------------------------------- >> 30 //bitwise right shift by 30
0000 0000 0000 0000 0000 0000 0000 0011 //you get only the first two bits, the rests are all replaced by 0
The second one:
1100 0001 0000 1100 1101 0110 0110 0000
--------------------------------------- >> 24 //bitwise right shift by 24
0000 0000 0000 0000 0000 0000 1100 0001
0011 1111 //this is 0x3f
--------------------------------------- & //this is bitwise-and
0000 0000 0000 0000 0000 0000 0000 0001 //you only get the 6 bits which you want
因此,您的第一个值将得到 3 (0000 0000 0000 0000 0000 0000 0000 0011)
,第二个值将得到 1 (0000 0000 0000 0000 0000 0000 0000 0001)
。
除了遵循上面的示例,我认为您也可以了解如何在许多其他不同情况下执行此操作。
我有一个 UInt32
变量,例如 3238844000。
现在我想得到这个数的前两位和前两位之后的6位。两个位都应该是 int。
Decimal: 3238844000
Binary: 11000001000011001101011001100000
^^
和
Decimal: 3238844000
Binary: 11000001000011001101011001100000
^^^^^^
更新二:
这种情况下的最简单(也是最快)的方法是纯粹 使用 bitwise-shift 运算符
int val = (int)(input >> 30); // performs the same
int val2 = (int)((input << 2) >> 26); //the simplest and the fastest way
我之前听说 bitwise-shift 操作往往会更快。但是今天,出于好奇*,我真的比较了 bitwise-shift + mask ((int)((input & mask2) >> 24)
) 和单独 bitwise-shift ((int)((input << 2) >> 26)
) 之间的性能。 bitwise-shift 单独操作大约 快 10%-15%。
这是我得到的结果:
[2016-01-20 04:01:26.638 UTC] shift-mask: 235 ms shift-only: 199 ms
[2016-01-20 04:01:30.402 UTC] shift-mask: 233 ms shift-only: 200 ms
[2016-01-20 04:01:31.265 UTC] shift-mask: 233 ms shift-only: 198 ms
[2016-01-20 04:01:32.116 UTC] shift-mask: 227 ms shift-only: 199 ms
[2016-01-20 04:01:32.850 UTC] shift-mask: 233 ms shift-only: 198 ms
[2016-01-20 04:01:33.584 UTC] shift-mask: 230 ms shift-only: 199 ms
[2016-01-20 04:01:34.280 UTC] shift-mask: 263 ms shift-only: 214 ms
[2016-01-20 04:01:35.055 UTC] shift-mask: 229 ms shift-only: 201 ms
[2016-01-20 04:01:36.996 UTC] shift-mask: 234 ms shift-only: 201 ms
[2016-01-20 04:01:37.933 UTC] shift-mask: 224 ms shift-only: 198 ms
[2016-01-20 04:01:38.353 UTC] shift-mask: 222 ms shift-only: 196 ms
[2016-01-20 04:01:38.798 UTC] shift-mask: 233 ms shift-only: 211 ms
[2016-01-20 04:01:39.246 UTC] shift-mask: 235 ms shift-only: 213 ms
[2016-01-20 04:01:39.668 UTC] shift-mask: 223 ms shift-only: 198 ms
[2016-01-20 04:01:41.102 UTC] shift-mask: 234 ms shift-only: 200 ms
[2016-01-20 04:01:41.524 UTC] shift-mask: 224 ms shift-only: 198 ms
[2016-01-20 04:01:41.948 UTC] shift-mask: 223 ms shift-only: 200 ms
[2016-01-20 04:01:42.373 UTC] shift-mask: 224 ms shift-only: 200 ms
[2016-01-20 04:01:43.521 UTC] shift-mask: 233 ms shift-only: 197 ms
[2016-01-20 04:01:44.272 UTC] shift-mask: 237 ms shift-only: 216 ms
[2016-01-20 04:01:44.909 UTC] shift-mask: 231 ms shift-only: 196 ms
[2016-01-20 04:01:45.353 UTC] shift-mask: 230 ms shift-only: 213 ms
[2016-01-20 04:01:45.850 UTC] shift-mask: 237 ms shift-only: 207 ms
[2016-01-20 04:01:46.276 UTC] shift-mask: 226 ms shift-only: 200 ms
[2016-01-20 04:01:47.074 UTC] shift-mask: 234 ms shift-only: 203 ms
[2016-01-20 04:01:47.718 UTC] shift-mask: 230 ms shift-only: 199 ms
[2016-01-20 04:01:48.144 UTC] shift-mask: 226 ms shift-only: 200 ms
[2016-01-20 04:01:48.567 UTC] shift-mask: 225 ms shift-only: 198 ms
[2016-01-20 04:01:48.994 UTC] shift-mask: 225 ms shift-only: 199 ms
[2016-01-20 04:01:49.429 UTC] shift-mask: 223 ms shift-only: 211 ms
[2016-01-20 04:01:49.860 UTC] shift-mask: 232 ms shift-only: 198 ms
[2016-01-20 04:01:50.284 UTC] shift-mask: 225 ms shift-only: 199 ms
注意:每个实验完成 (5,000,000 x 100) 次操作。
*记得我过去与 micro-controllers 打交道的日子……;)
原文:
就像您如何找到 UInt32
的二进制表示一样,您应该在其 二进制表示[=81= 中找到正确的 位掩码 ] 也是:
uint mask1 = 0xC0000000; //1100 0000 0000 0000 0000 0000 0000 0000
uint mask2 = 0x3F000000; //0011 1111 0000 0000 0000 0000 0000 0000
然后将它们与 bitwise-and operator
一起使用要获得前两位,您可以像这样简单地使用掩码:
uint val = input & mask1; //should give you the first two bits, the rests are zero
并获取接下来的 6 位:
uint val2 = input & mask2; //similarly, should give you only the six bits in the position which you want
如果你在 int
中需要它们,那么简单地转换它们:
int val = (int)(input & mask1);
int val2 = (int)(input & mask2);
如果你想把结果放在 LSB 中(最低位 byte
,最右边 8-bit
在这种情况下),使用 按位右移 运算符:
int val = (int)((input & mask1) >> 30); //30 bits are 0
int val2 = (int)((input & mask2) >> 24); //24 bits are 0
更新:
至于上面的移位版本,实际上,你也可以简单地按位右移第一个,对第二个做几乎类似的操作,除了它需要一个0x3F
(0011 1111
) 的按位掩码 以清除不需要的前两位。
int val = (int)(input >> 30); // performs the same
int val2 = (int)((input >> 24) & 0x3F); //the simpler way
他们在bit-representation中发生的事情如下(我给出评论是为了简化逻辑流程):
The first one:
1100 0001 0000 1100 1101 0110 0110 0000
--------------------------------------- >> 30 //bitwise right shift by 30
0000 0000 0000 0000 0000 0000 0000 0011 //you get only the first two bits, the rests are all replaced by 0
The second one:
1100 0001 0000 1100 1101 0110 0110 0000
--------------------------------------- >> 24 //bitwise right shift by 24
0000 0000 0000 0000 0000 0000 1100 0001
0011 1111 //this is 0x3f
--------------------------------------- & //this is bitwise-and
0000 0000 0000 0000 0000 0000 0000 0001 //you only get the 6 bits which you want
因此,您的第一个值将得到 3 (0000 0000 0000 0000 0000 0000 0000 0011)
,第二个值将得到 1 (0000 0000 0000 0000 0000 0000 0000 0001)
。
除了遵循上面的示例,我认为您也可以了解如何在许多其他不同情况下执行此操作。