繁体   English   中英

将 uint32_t 与 uint64_t 连接和拆分的最佳方法

[英]best way to concatenating and splitting uint32_t to/from uint64_t

这段代码怎么样

#include <cstdio>
#include <cinttypes>
#include <type_traits>
#include <cstddef>
#include <iostream>

int main()
{
    uint64_t tsc = 0xdeaddeadc0dec0de;
    uint32_t MSB = *((uint32_t*)&tsc+1);
    uint32_t LSB = *((uint32_t*)&tsc);
    std::printf("low   %x high %x \n", LSB,MSB);
    uint64_t MLSB = 0;
    *((uint32_t*)&MLSB) = LSB;
    *((uint32_t*)&MLSB+1) = MSB;
    std::printf("highlow %lx \n", MLSB);
    uint64_t LMSB = 0;
    *((uint32_t*)&LMSB+1) = LSB;
    *((uint32_t*)&LMSB) = MSB;
    std::printf("lowhigh %lx \n", LMSB);
}

问题 go 这段代码有什么问题? 它是否依赖于机器成为大端? 可能是。 所以对于 Little-endian LSB 和 MSB 位置会改变,或者你可以通过使用系统宏使它自动进行转变和类型铸造?

如果您认为必须在代码中处理字节顺序,那您就大错特错了。

uint64_t tsc = 0xdeaddeadc0dec0de;
uint32_t MSB = tsc >> 32;
uint32_t LSB = tsc;
uint64_t MLSB = LSB | (static_cast<uint64_t>(MSB)) << 32;
uint64_t LMSB = MSB | (static_cast<uint64_t>(LSB)) << 32;

这就是您所需要的。 数字就是数字。 他们没有字节顺序。 数字表示具有字节顺序。 不要处理表示,处理数字。

有关更多信息,请阅读字节顺序谬误

由于所谓的严格别名规则,C++ 中的类型双关是不允许的。

此外,该代码在大端或中端机器上根本无法运行。

一个简单正确的解决方案是使用位移:

uint64_t tsc = 0xdeaddeadc0dec0de;
uint32_t MSB = (uint32_t)(tsc >> 32);
uint32_t LSB = (uint32_t)(tsc);
std::printf("low   %x high %x \n", LSB, MSB);

uint64_t MLSB = ((uint64_t)MSB << 32) | LSB;
std::printf("highlow %lx \n", MLSB);

暂无
暂无

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

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