将由0和1组成的十六进制转换为二进制等效值

时间:2018-04-25 00:08:22

标签: c binary hex bit-manipulation

我需要一个十六进制数转换为另一个表示它的二进制值的数字(虽然不是实际值)。

例如,如果我有0x0101,我想得到0b0101,这意味着0x5。我在开头得到的十六进制总是由0和1组成。

它也可以是一种将0xf00f转换为0b1001(0xf为0b1而不是0x1为0b1)的方法,即0x9。实际上,我在开头的十六进制数字由f和0组成,但很容易将f除以1替换为0xf。例如:

ApplyTo<T>() where T : Form

或:

shared_preferences: "0.3.3"

编辑:我知道我可以通过循环轻松完成它,但我想知道我是否可以使用按位操作符执行某些操作。此外,我无权访问uint16_t bitMask = 0xf0f0; uint16_t nybbleMask = 0; //do some bit manipulation with bitMask //get nybbleMask == 0xc (0b1010) 库。

2 个答案:

答案 0 :(得分:2)

16位十六进制的一行修复就是......

sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}

虽然这不是你想要的按位操作。不确定bin = ((hex%16)?1:0) + (((hex/16)%16)?2:0) + (((hex/256)%16)?4:0) + (((hex/4096)%16)?8:0); 是否适用>>或至少指定为始终适用于int - 您可能需要查看this question以考虑按位运算符和{{1} - 如果没问题那么

uint16_t
如果您的uint16_t字节为bin = (hex & 1) | (((hex >> 4) & 0x1) << 1) | (((hex >> 8) & 0x1) << 2) | (((hex >> 12) & 0x1) << 3); hex,则

会有效。

任意大小十六进制的旧答案在

之下
F

这应该将任何0x ....转换为0b ....如果十六进制数字不等于零,则每个数字得到1。关键部分是0,它测试int hex; int bin; int n, m, k; //assume hex has your hex value n=0; bin=0; while(pow(16.0,(double)n)<(double)hex+0.5) // test if we are done { m=1; for(k=0;k<n;k++) m*=16; if ((hex/m)%16!=0) { m=1;for(k=0;k<n;k++) m*=2; bin += m; } n++; } 数字的第n个数字,看它是零还是非零。

答案 1 :(得分:2)

这是一个非常简单的问题,我认为这是一项功课。 @tom让它变得比它需要的更难。

您只想从最低有效位开始提取每4位,忽略3个中间零。我会给你一个算法。编写代码应该不难:

let x be the hex coded binary number to convert
let val be the binary result value, initially zero
let n be the bit position we're currently finding, initially zero
while x is not zero
  let b be the least significant bit of x
  update val to be val or (b shifted left by n bits)
  increment n
  update x to be x shifted right by 4 bits

这是另一种方法:

let val be 0
let hex_mask be 1
let bin_mask be 1
while hex_mask is not zero
  if (x and hex_mask) is non-zero, then update val to be val or bin_mask
  shift hex_mask left 4 bits
  shift bin_mask left 1 bit

<强>加成

既然你说它不是家庭作业,那么让我告诉你第二个解决方案 是一个只有按位运算符的解决方案,如果你有一个好的编译器。

这是代码:

uint16_t hex_coded_binary_value(uint16_t x) {
  uint16_t val = 0;
  for (uint16_t h = 1, b = 1; h; h <<=4, b <<= 1)
    if (x & h) val |= b;
  return val;
}

如果您使用最新版本的Apple clang进行编译,则会获得:

mov eax, edi
and eax, 1
mov ecx, edi
shr ecx, 3
and ecx, 2
or ecx, eax
mov eax, edi
shr eax, 6
and eax, 4
or eax, ecx
shr edi, 9
and edi, 8
lea eax, [rdi + rax]
ret

注意没有循环!这一切都是转变,和,或者,添加和移动。 gcc使用条件移动指令,但也没有循环。

编译器发现的算法是什么?如果你用C编码,它看起来像是:

val = (x & 1)
    | ((x >> (4 - 1)) & (1 << 1))
    | ((x >> (8 - 2)) & (1 << 2))
    | ((x >> (12 - 3)) & (1 << 3));

折叠为

val = (x & 1) | ((x >> 3) & 2) | ((x >> 6) & 4) | ((x >> 9) & 8);

请注意,结果的操作少于@ tom的解决方案。

这也编译为与原始版本基本相同,但C更长,更容易出错。道德是信任你的编译器。