簡體   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