簡體   English   中英

如何檢查 integer 中是否恰好設置了一位?

[英]How to check whether exactly one bit is set in an integer?

我想寫一個 function HasOneBit ,那個

  • 接受任何 integer 類型(有符號或無符號,8 到 64 位),
  • constexpr
  • 不調用未定義的行為。

我試圖概括這一點:

bool HasOneBit (std::uint64_t value)
{
    return value != 0 && (value & (value - 1)) == 0;
}

如果value的類型是帶符號的 integer,並且我們將最小值傳遞給 function,那么這會下溢。我是否必須重載 function 8 次才能實現所有可能性?

以下模板 function 滿足所有條件(現場演示):

template <class T>
constexpr bool HasOneBit (T value)
{
    static_assert (std::is_integral<T>::value && !std::is_same<T, bool>::value,
                   "This function should be used only with integers.");

    const std::make_unsigned_t<T> unsignedValue = value;

    return unsignedValue != 0 && (unsignedValue & (unsignedValue - 1)) == 0;
}

這不會調用未定義的行為,因為value首先被轉換為T的無符號對應物。 此轉換不會更改value的位表示形式。

我認為,標准的相關引用是這樣的(參見N4713 ,[conv.integral]#2):

如果目標類型是無符號的,則結果值是與源 integer 一致的最小無符號 integer(模2 n ,其中n是用於表示無符號類型的位數)。 [注意:在二進制補碼表示中,此轉換是概念性的,位模式沒有變化(如果沒有截斷)。 ——尾注]

此規則的更新版本甚至更簡單。 不確定,這是否也適用於無符號到有符號的轉換。

否則,結果是與源 integer 模2 N一致的目標類型的唯一值,其中N是目標類型的寬度。

暫無
暫無

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

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