我怎样才能正确移动这个 uint64_t 号码?
How can I correctly shift this uint64_t number?
我正在编写一个小测试程序,将 64 位数字从小端格式转换为大端格式。
int main(void){
uint64_t value1 = 1234;
uint64_t value2 = 0;
uint64_t constant = 0xFF00000000000000;
uint8_t i;
for(i = 0; i < 4; i++){
int8_t shift = 56 - 16 * i; // Gives me the sequence 56, 40, 24, 8.
value2 |= (value1 & constant) >> shift;
constant = constant >> 2;
}
for(i = 0; i < 4; i++){
int8_t shift = 16 * i + 8; // Gives me the sequence 8, 24, 40, 56. value2 |= (value1 & constant) << shift;
constant = constant >> 2;
}
printf("\n\nvalue1: %" PRIu64, value1);
printf("\nvalue2: %" PRIu64, value2);
}
有点复杂,但我对移位操作有疑问。该行
constant = constant >> 2;
没有达到我的预期。我希望 0xFF00000000000000
在一个循环后变成 0x00FF000000000000
,依此类推。相反,它变成 0x3FC0000000000000
。
我假设其他轮班操作也存在类似问题。谁能解释一下?
我的第一个猜测是按位运算符只能在 32 位数字上正确工作。在这种情况下,我可以转换一个 32 位指针并一次处理每个 32 位块。但我想避免这种情况,因为它更加复杂。
>> 运算符按运算符右侧的位数进行位移。如果要移动超过 1 个字节(2 个半字节),则应使用 constant >> 8
。无论应用移位的变量的大小如何,它的工作原理都完全相同。
在使用按位运算符时必须如此。看下面简单的解释。
在你的情况下 0xFF0000...000
实际上是 0b111111110000...000
的二进制表示。当你一定读过二进制的 0000 到 1111 实际上是十六进制表示的 0 到 F。这个按位运算符在位级运行,所以在我们进一步研究之前,这个十六进制表示需要分解成二进制。
现在移动 2 位给出 0b001111111100...000
。仔细观察,这是 0b<0011><1111><1100>00...000
实际上是 0x3FC00...000
希望解释清楚!
我正在编写一个小测试程序,将 64 位数字从小端格式转换为大端格式。
int main(void){
uint64_t value1 = 1234;
uint64_t value2 = 0;
uint64_t constant = 0xFF00000000000000;
uint8_t i;
for(i = 0; i < 4; i++){
int8_t shift = 56 - 16 * i; // Gives me the sequence 56, 40, 24, 8.
value2 |= (value1 & constant) >> shift;
constant = constant >> 2;
}
for(i = 0; i < 4; i++){
int8_t shift = 16 * i + 8; // Gives me the sequence 8, 24, 40, 56. value2 |= (value1 & constant) << shift;
constant = constant >> 2;
}
printf("\n\nvalue1: %" PRIu64, value1);
printf("\nvalue2: %" PRIu64, value2);
}
有点复杂,但我对移位操作有疑问。该行
constant = constant >> 2;
没有达到我的预期。我希望 0xFF00000000000000
在一个循环后变成 0x00FF000000000000
,依此类推。相反,它变成 0x3FC0000000000000
。
我假设其他轮班操作也存在类似问题。谁能解释一下?
我的第一个猜测是按位运算符只能在 32 位数字上正确工作。在这种情况下,我可以转换一个 32 位指针并一次处理每个 32 位块。但我想避免这种情况,因为它更加复杂。
>> 运算符按运算符右侧的位数进行位移。如果要移动超过 1 个字节(2 个半字节),则应使用 constant >> 8
。无论应用移位的变量的大小如何,它的工作原理都完全相同。
在使用按位运算符时必须如此。看下面简单的解释。
在你的情况下 0xFF0000...000
实际上是 0b111111110000...000
的二进制表示。当你一定读过二进制的 0000 到 1111 实际上是十六进制表示的 0 到 F。这个按位运算符在位级运行,所以在我们进一步研究之前,这个十六进制表示需要分解成二进制。
现在移动 2 位给出 0b001111111100...000
。仔细观察,这是 0b<0011><1111><1100>00...000
实际上是 0x3FC00...000
希望解释清楚!