十六进制数的C位操作
有没有一种方法可以访问C中十六进制数的某些部分 我想写一个函数,它接受一个十六进制数并求反,但保留最低有效字节不变。示例:0x87654321应变为0x789ABC21 我试图以某种方式保存LSB,然后将其应用于求反的x,但我的问题是我的掩码应用于所有字节。我可以为特定的值硬编码,但显然这不是我想要的十六进制数的C位操作,c,hex,C,Hex,有没有一种方法可以访问C中十六进制数的某些部分 我想写一个函数,它接受一个十六进制数并求反,但保留最低有效字节不变。示例:0x87654321应变为0x789ABC21 我试图以某种方式保存LSB,然后将其应用于求反的x,但我的问题是我的掩码应用于所有字节。我可以为特定的值硬编码,但显然这不是我想要的 void b(int x) { int temp = x & 0xFF; // temp is all 0 with the LSB being the same as x's x
void b(int x) {
int temp = x & 0xFF; // temp is all 0 with the LSB being the same as x's
x = ~x; // this negates x
// one of a couple of attempts I tried thus far:
// x = (x & 0x00) | temp;
// idea: change x's LSB to 00 and OR it with temp,
// changing x's LSB to temp's LSB
}
如果您不发布解决方案的代码,而只是回答是否有方法将位运算应用于十六进制数的特定部分,或者我如何解决此问题,我将不胜感激。通常,您可以使用掩码对值的特定位进行运算 掩码是一种位模式,在需要操作的位置有1,在不需要操作的位置有0 看起来您需要3个操作:提取最低字节、求反、恢复最低字节。你们可以算出否定,所以我将只讨论提取一个位字段和恢复一个提取的位字段 要提取指定的位,请对所需位使用带1的掩码,并使用按位and运算符
&
。and运算符为掩码的所有0设置0,当掩码为1时,它从另一个参数复制位。如果需要在程序中的其他位置检查该值,也可以方便地将该值右移到最低位置(以便更容易在表中查找)
若要还原保存的位,请在先前将其下移时将其上移。然后从值中清除这些位,并使用inclusive或|
作为所有一位的位和。要清除值中的位,请使用第一次操作中掩码的倒数。例如,y=x&0xf
保存一个半字节,x&~0xf
清除该半字节,(x&~0xf)| y
重新组合为相同的原始x
编辑:
如果要提取的片段不在最低位置,比如32位无符号整数的第二个字节(LSB),那么将提取的值移到零位置以处理它可能会很有用
x = 0x12345678;
y = x & 0xFF00; // == 0x5600
y >>= 8; // == 0x56
但如果这样做,则必须先将其移回正确位置(当然),然后再使用位字段的新值更新较大的值
x = (x & ~0xFF00) | (y << 8);
x=(x&~0xFF00)|(y如果我正确理解了这个问题,它似乎是这样的(未经测试)
我找到了一种操作所选字节的方法。(!!!这将是CS:APP的家庭作业2.60!!!)
如果0x12345678是类型为int的给定十六进制值,则这样做将允许我更改第i个字节:
int x = 0x12345678;
unsigned char* xptr = (unsigned char*) &x;
xptr[i] = 0; // say i=2, then this would yield: 0x120045678
现在,如果我想在字节I的位置添加一个值,比如0xAB,我会做luser droog已经提到的事情:
int temp = 0xAB;
temp = temp << i*8; // say i=2, then this would yield: 0x00AB0000
x = x | temp; // this yields the desired result 0x12AB3456
int-temp=0xAB;
Timp = Timp,我对C不太熟悉,那么java或C++中的具体操作和做的是逻辑比较,但是这里没有什么意义,是不是?<代码> x=(~x和~0xFF)(x和0xFF)。
虽然我希望得到一个指导性的答案,而不是一些代码,但我仍然很感激。谢谢李,这确实有效。我知道,但正如我所说,我的掩码应用于所有位。掩码是一个工具,通过控制二进制操作的真值表来选择要应用的位。好的。我确实让它与您一起工作r方法-好吧,基本上我做了李·丹尼尔·克罗克已经建议过的同样的事情。虽然我不太理解正确移位的部分。你能详细说明一下,或者举个小例子吗?@Beko编辑了更多关于移位的内容。他说LS byte,而不是bit,你的代码依赖于32位int,所以你的常量应该是~0xFF
和0xFF
@LeeDanielCrocker:没有注意到是字节而不是位。更新了。当,按照说明浪费了我的时间如果你不发布解决方案的代码,我将不胜感激。
不,你没有。只是你最初的答案不太正确。好的。很抱歉抱怨。:)
int temp = 0xAB;
temp = temp << i*8; // say i=2, then this would yield: 0x00AB0000
x = x | temp; // this yields the desired result 0x12AB3456