由于我的一位同事正在休假,我对C语言并不了解,因此我遇到了问题。
我有一个32位的数字,我必须从中提取位。我确实经历了几个线程,但我仍然不清楚如何这样做。如果有人可以帮助我,我将非常感激。
以下是我需要做的一个例子:
假设十六进制数= 0xD7448EAB。 二进制= 1101 01 11 0100 0100 1000 11 10 1010 1011 我需要提取16位,然后输出该值。我想要第10到25位。
忽略低10位(十进制)。即10 1010 1011被忽略 并且忽略高6位(溢出)。即,1101 01被忽略。
其余16位数据需要输出为11 0100 0100 1000(需要斜体数字作为输出)。
这是一个例子,但我将一直保持不同的十六进制数字,我需要提取与我解释的相同的位。
我如何解决这个问题?
谢谢。
对于此示例,您将输出1101 0001 0010 0011,即0xD123或53,539十进制。
答案 0 :(得分:3)
好的,这是我写的方式:
#include <stdint.h>
#include <stdio.h>
main() {
uint32_t in = 0xd7448eab;
uint16_t out = 0;
out = in >> 10; // Shift right 10 bits
out &= 0xffff; // Only lower 16 bits
printf("%x\n",out);
}
in >> 10
将数字右移10位; & 0xffff
丢弃除低16位以外的所有位。
答案 1 :(得分:2)
您需要掩码来获取所需的位。 Masks 是您可以用来以您想要的方式筛选位的数字(保留位,删除/清除位,修改数字等)。您需要知道的是 AND,OR,XOR,NOT和移位操作。根据您的需要,您只需要一对夫妇。
你知道转移: x << y
将位从 x * y位置移动到左边*。
如何按顺序将x位设置为1: (1 << x) - 1
如何将x位按顺序设置为1,从y开始到y + x: ((1 << x) -1) << y
以上是您需要的位掩码。因此,例如,如果您想要16位0xD7448EAB,从10到25,您需要上述内容,因为x = 16且y = 10.
现在要获得你想要的位,只需 AND 使用上面的掩码编号0xD7448EAB,你就可以得到掩码 0xD7448EAB只有你的位想。之后,如果您想要浏览每一个,您需要将结果向右移动10并一次处理每个位(位置0)。
答案可能会更长一些,但它的设计要好于使用0xff或其他任何方式进行硬编码。
答案 2 :(得分:1)
我想要第10到25位。
你可以这样做:
unsigned int number = 0xD7448EAB;
unsigned int value = (number & 0x3FFFC00) >> 10;
或者这个:
unsigned int number = 0xD7448EAB;
unsigned int value = (number >> 10) & 0xFFFF;
答案 3 :(得分:1)
我将上面的前2个答案结合起来编写了一个C程序,它提取32位无符号整数的任何比特范围(不仅仅是10到25)的位。函数的工作方式是将lo
的位hi
返回到num
的{{1}}。
#include <stdio.h>
#include <stdint.h>
unsigned extract(unsigned num, unsigned hi, unsigned lo) {
uint32_t range = (hi - lo + 1); //number of bits to be extracted
//shifting a number by the number of bits it has produces inconsistent
//results across machines so we need a special case for extract(num, 31, 0)
if(range == 32)
return num;
uint32_t result = 0;
//following the rule above, ((1 << x) - 1) << y) makes the mask:
uint32_t mask = ((1 << range) -1) << lo;
//AND num and mask to get only the bits in our range
result = num & mask;
result = result >> lo; //gets rid of trailing 0s
return result;
}
int main() {
unsigned int num = 0xd7448eab;
printf("0x%x\n", extract(num, 10, 25));
}