C语言 C 十六进制数的按位运算
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28242415/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C bit-wise operations with hex numbers
提问by Beko
Is there a way to access certain parts of a hexadecimal number in C?
有没有办法在 C 中访问十六进制数的某些部分?
I want to write a function that takes in a hexadecimal number and negates it, but leaves the least significant byte unchanged. Example: 0x87654321 should become 0x789ABC21.
我想编写一个函数,它接受一个十六进制数并将其取反,但保持最低有效字节不变。例如:0x87654321 应该变成 0x789ABC21。
I've tried to somehow save the LSB and then apply it to the negated x, but my problem is that my mask gets applied to all bytes. I could hard code it for a specific value, but obviously that's not what I want.
我试图以某种方式保存 LSB,然后将其应用于否定的 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
}
I'd appreciate if you don't post code for the solution, but rather just answer whether there is a way to apply bit operations to specific sections of a hexadecimal number, or how I could possibly solve this.
如果您不发布解决方案的代码,我会很感激,而只是回答是否有办法将位操作应用于十六进制数的特定部分,或者我如何可能解决这个问题。
回答by luser droog
In general you can operate on specific bits of a value by using a mask.
通常,您可以使用掩码对值的特定位进行操作。
A mask is bit-pattern with 1s where you want to operate and 0s where you don't.
掩码是位模式,您要操作的位置为 1,不操作的位置为 0。
It seems like you need 3 operations: extract lowest byte, negate, restore lowest byte. You can figure out negation, so I'll just talk about extracting a bit-field and restoring an extracted bit-field.
似乎您需要 3 个操作:提取最低字节、否定、恢复最低字节。你可以找出否定,所以我只讨论提取位域和恢复提取的位域。
To extract specified bits, use a mask with 1s for the desired bits and use the bitwise andoperator &. The andoperator sets 0s for all 0s of the mask, and where the mask is 1, it copies the bits from the other argument. If you need to examine this value elsewhere in your program, it may also be convenient to right-shift >>the value down to the lowest position (so it's easier to lookup in tables).
要提取指定位,请对所需位使用带 1 的掩码,并使用按位和运算符&。的和操作员设置为0掩模的全部为0,并且其中所述掩模是1,它拷贝从其它参数的位。如果您需要在程序的其他地方检查这个值,>>将值右移到最低位置也可能很方便(这样更容易在表格中查找)。
To restore saved bits, shift back up if you shifted it down earlier. Then clear those bits from the value, and use inclusive-or|as a bitwise sum of all one bits. To clear the bits from the value, use the inverse of the mask from the first operation. Ie. y = x & 0xfsaves a nibble, x & ~0xfclears that nibble, (x & ~0xf) | yrecombines to the same original x.
要恢复保存的位,如果您之前将其向下移,请向上移回。然后从值中清除这些位,并使用inclusive-or|作为所有一位的按位和。要清除值中的位,请使用第一个操作中的掩码的反转。IE。y = x & 0xf保存一个半字节,x & ~0xf清除该半字节,(x & ~0xf) | y重新组合为相同的原始 x。
Edit:If the piece you're extracting is not in the lowest position, say the second byte (LSB) from a 32 bit unsigned integer, then it may be useful to shift the extracted value to the zero position to work with it.
编辑:如果您提取的部分不在最低位置,例如 32 位无符号整数的第二个字节 (LSB),那么将提取的值移到零位置以使用它可能很有用。
x = 0x12345678;
y = x & 0xFF00; // == 0x5600
y >>= 8; // == 0x56
But if you do this then you have to shift it back to the correct position (of course) before updating the larger value with a new value for the bitfield.
但是如果你这样做,那么你必须在用位域的新值更新更大的值之前将它移回正确的位置(当然)。
x = (x & ~0xFF00) | (y << 8);
回答by Jonathan Wood
If I correctly understood the question, seems like it would be something like this (untested).
如果我正确理解了这个问题,看起来就像这样(未经测试)。
void b(int x) {
return (~x & ~0xFF) | (x & 0xFF);
}
回答by Beko
I've found a way to manipulate a chosen byte. (!!! This would be homework 2.60 of CS:APP !!!)
我找到了一种操作所选字节的方法。(!!!这将是 CS:APP 的作业 2.60 !!!)
If 0x12345678 is a given hexadecimal value of type, say int, then doing this will allow me to change the ith byte:
如果 0x12345678 是一个给定的十六进制值类型,比如 int,那么这样做将允许我更改第 i 个字节:
int x = 0x12345678;
unsigned char* xptr = (unsigned char*) &x;
xptr[i] = 0; // say i=2, then this would yield: 0x120045678
Now, if I want to add a value in the position of byte i, say 0xAB, I'd do what luser droog already mentioned:
现在,如果我想在字节 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

