簡體   English   中英

構造有符號的位域

[英]constructing signed bit-fields

下面,我構造了一個使用位域的代碼示例。 在實現比較運算符時,我注意到它沒有按預期工作。 問題是-1似乎不小於1。

考慮了一段時間后,我發現構造函數中的掩碼存在問題。

我在此處添加了“ aValue&MAX_VALUE”,因為否則編譯器會發出轉換警告。 但是,先用MAX_VALUE進行掩碼,然后強制轉換為int32_t並不能得到正確的結果。

有誰知道我該如何解決? 當我寫minusOne.v = -1;時,似乎確實得到了預期的結果minusOne.v = -1; 在main()方法中。 但是我不確定如何在構造函數中編寫它(沒有得到轉換警告)。

#include <iostream>
#include <cstdint>

using namespace std;

struct int27_t
{
    int32_t v:27;

    constexpr static int32_t MIN_VALUE = -(1L << 26);
    constexpr static int32_t MAX_VALUE = (1L << 26) - 1;
    constexpr static int32_t MASK = 0x7FFFFFF;

    int27_t() : v(0) {}

    explicit int27_t(int32_t aValue) : v(static_cast<int32_t>(aValue & MAX_VALUE)) {}

    friend bool operator<(const int27_t& aLhs, const int27_t& aRhs);
};

bool operator<(const int27_t& aLhs, const int27_t& aRhs)
{
    return aLhs.v < aRhs.v;
}

int main()
{
    int27_t minusOne{-1};
    int27_t plusOne{1};
    cout << "MAX_VALUE == " << int27_t::MAX_VALUE << " == 0x" << hex << int27_t::MAX_VALUE << dec << endl;
    cout << "-1 == " << minusOne.v << " == 0x" << hex << minusOne.v << dec << endl;
    cout << "-1 cast to int32_t: " << static_cast<int32_t>(minusOne.v) << " == 0x" << hex << static_cast<int32_t>(minusOne.v) << dec << endl;
    cout << "-1 < 1 ? " << (minusOne < plusOne) << endl;
    cout << endl;
}

程序輸出

MAX_VALUE == 67108863 == 0x3ffffff
-1 == 67108863 == 0x3ffffff
-1 cast to int32_t: 67108863 == 0x3ffffff
-1 < 1 ? 0

布爾運算不適用於有符號類型。 您只需&刪除構造函數中的符號。

您的代碼基本上有四個問題:

  1. 不要對有符號類型使用二進制算術。 只是不要這樣做。 如果確實有必要,則將其算術轉換為unsigned (乘以-1並注意溢出),執行某些操作,然后再算術返回有符號。
  2. 您依賴於簽名數字的某種表示形式。 據我所知(涉及符號類型的是C99),該語言提供了三個不同的符號符號和大小一個補碼兩個補碼 ,請參見。 ISO / IEC 9899:TC2§6.2.6.2-2。
  3. 假設2的補碼對幾乎所有最新平台都適用,那么您的MIN_VALUEMIN_VALUE 1。
  4. 請不要使用位域。 幾乎所有最新的體系結構都將其擴展為某些字大小的類型。 除了麻煩之外,您可能一無所獲,因為帶符號的溢出是未定義的行為。 因此,以這種方式限制簽名類型的范圍沒有意義。

暫無
暫無

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

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