简体   繁体   English

我如何正确地移动此uint64_t数字?

[英]How can I correctly shift this uint64_t number?

I'm writing a small test program that converts 64-bit numbers from little-endian to big endian format. 我正在编写一个小型测试程序,该程序可以将64位数字从little-endian格式转换为big-endian格式。

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);
}

It's a little convoluted, but it's the bitwise shift operations I have a problem with. 这有点令人费解,但这是我有问题的按位移位操作。 The line 线

constant = constant >> 2;

doesn't give me what I expect. 没有给我我所期望的。 I expect 0xFF00000000000000 to become 0x00FF000000000000 after one loop, and so on. 我希望0xFF00000000000000在一个循环后变为0x00FF000000000000 ,依此类推。 Instead, it becomes 0x3FC0000000000000 . 而是变为0x3FC0000000000000

I assume there's also a similar problem with the other shift operations. 我认为其他班次操作也存在类似问题。 Can anyone explain? 谁能解释?

My first guess is that bitwise operators only work correctly on 32-bit numbers. 我的第一个猜测是按位运算符只能在32位数字上正常工作。 In which case, I could cast a 32-bit pointer and deal with each 32-bit block one at a time. 在这种情况下,我可以强制转换一个32位指针并一次处理每个32位块。 But I'd like to avoid that since it's even more convoluted. 但我想避免这种情况,因为它更加令人费解。

This has to be when working with bitwise operator. 这必须在使用按位运算符时使用。 Look at the simple explanation below. 请看下面的简单说明。

In your case 0xFF0000...000 is actually 0b111111110000...000 in binary representation. 在您的情况下, 0xFF0000...000实际上是二进制表示形式的0b111111110000...000 When you must have read about 0000 to 1111 in binary is actually 0 to F in hex representation. 当必须以二进制读取0000至1111时,实际上是以十六进制表示为0至F。 This bitwise operator operates bit-level so this hex representation needs to be broken to a binary before we look into further. 该按位运算符按位进行操作,因此在进一步研究之前,需要将此十六进制表示形式分解为二进制。

Now shifting 2 bits give out 0b001111111100...000 . 现在将2位移位给出0b001111111100...000 Observing closely, this is 0b<0011><1111><1100>00...000 which is actually 0x3FC00...000 仔细观察,这是0b<0011><1111><1100>00...000 ,实际上是0x3FC00...000

Hope it explained! 希望它能解释!

The >> operator does a bit-shift by the amount of bits at the right of the operator. >>运算符按运算符右侧的位数进行位移。 You should use constant >> 8 if you want to move over 1 bytes (2 nibbles). 如果要移动1个字节(2个半字节),则应使用constant >> 8 It works exactly the same no matter the size of the variable on which the shift is being applied. 无论要应用移位的变量的大小如何,它的工作原理都完全相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM