簡體   English   中英

在整數中設置更高的位,而不管其中的位數

[英]Set higher bits in an integer irrepective of number of bits in it

我想使用整數的上半部分來存儲一些值。 現在在上半部分,我想再次存儲兩個不同的值,如下所示。

如果long是 32 位,我想使用前 8 位和接下來的 8 位(從左起)。

如果long是 64 位,我想使用前 16 位和接下來的 16 位(從左起)。 我想出了類似下面的東西。

unsigned long foo;
unsigned long bar = 1UL; // i'll ensure this value fits in 2 bits to handle 16 bits integer.
unsigned long baz = 1UL; // i'll ensure this value fits in 2 bits.
int BitsInLong = CHAR_BIT * sizeof(unsigned long);
foo |= bar << (BitsInLong / 2 + BitsInLong / 4);
foo |= baz << (BitsInLong / 2);

雖然這似乎有效,但在某些情況下這可能會失敗還是可能有更好的解決方案。

只有一個問題 - 字段溢出。 如果(近)中間字段設置了一個大值,該值可能會溢出到下一個字段。

這是一個通用解決方案,適用於位數可被 4 整除的類型(適用於標准系統上的所有常規類型):

template <typename T, unsigned Field>
constexpr T make_field(unsigned value)
{
  static_assert(std::numeric_limits<T>::is_integer, 
                  "works only with integers");
  static_assert(Field <4, "a field can be 0,1,2,3 ");
  using UT = typename std::make_unsigned<T>::type;
  constexpr unsigned bits = std::numeric_limits<UT>::digits;
  static_assert(bits % 4 == 0, "number of bits in return type must be divisible by 4");
  auto mask = ((UT)1 << (bits / 4)) - 1;
  return (value & mask) << ((3 - Field) * bits / 4);
}

和用法

int main()
{   
     // will print 700, since upper bits are truncated.
    std::cout << std::hex << (make_field<int12_t, 1>(0x127) << '\n';

    // will print 7000
    std::cout  << (make_field<int12_t, 0>(0x127) << '\n';

    // prints 1234
    std::cout << (make_field<int, 0>(0x12) | make_field<int, 1>(0x34)) << "\n";
}                           

注意:如果有符號整數類型不是二進制補碼格式,並且高位已設置,則它們可能會以不可預測的方式工作。

模板化聯合怎么樣?

template <typename T>
union segmentedStorage {
  std::array<unsigned char, sizeof(T)> byteRepr;
  T     fullRepr;
  static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value);
  static_assert(sizeof(T) % 4 == 0);
};

Godbolt 示例: https ://godbolt.org/z/R0vtfT

對於 ::value 類型,這需要 C++17。 注意嚴格的別名規則。 我想您會想要編寫字節表示,然后讀取完整的表示,但從技術上講,這是未定義的行為。 我認為GCC 保證這將按預期運行。 Clang 可能不會。 可以在此處此處找到有關 GCC 如何允許這種未定義行為的更多詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM