c++ - 构造带符号的位域

标签 c++ bit-fields

下面我构建了一些我正在处理的使用位域的代码的小示例。 在实现比较运算符时,我注意到它没有按预期工作。问题是 -1 似乎不小于 1。

考虑了一段时间后,我觉得构造函数中的屏蔽有问题。

我在那里添加了“aValue & MAX_VALUE”,否则编译器会发出转换警告。但是,首先使用 MAX_VALUE 进行屏蔽,然后转换为 int32_t 并没有给我正确的结果。

有谁知道我该如何解决这个问题? 当我在 main() 方法中编写 minusOne.v = -1; 时,我似乎确实得到了预期的结果。但我不确定如何在构造函数中编写它(没有收到转换警告)。

#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

最佳答案

bool 运算不适用于有符号类型。 您只是简单地 &-ing 掉构造函数中的符号。

您的代码基本上有四个问题:

  1. 不要对有符号类型使用二进制算术。只是不要这样做。如果真的有必要,算术转换为unsigned(乘以-1并注意溢出),做一些事情然后返回到算术签名。
  2. 您依赖于带符号数字的某种表示。据我所知(关于符号类型的 C99),该语言提供三种不同的:符号和大小一个补码两个补码,比照。 ISO/IEC 9899:TC2 §6.2.6.2-2。
  3. 假设 二进制补码(几乎所有最新平台都适用),您的 MIN_VALUE 相差 1。
  4. 请不要使用位字段。几乎所有最近的架构都会将其扩展为某种字大小的类型。你可能除了麻烦什么也得不到,因为有符号溢出是未定义的行为。因此,以这种方式限制签名类型的范围毫无意义。

关于c++ - 构造带符号的位域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41941683/

相关文章:

android - 为 Android 构建 FFmpeg 以使用命令行参数

c++ - 启用从 `vector<const T>&` 到 `const vector<T>&` 的隐式转换

c - 如何将结构转换为 uint8_t(错误 : conversion to non-scalar type requested)

python - 创建一个带有位域的枚举

c - C 中的位域数组

c++ - 枚举类型的位域和存储在其中的值

c - 套接字编程中的霍夫曼编码

c++ - boost::atomic 真的可以通过减少多线程系统调用(在互斥/信号量中)的开销来 boost 性能吗?

c++ - 什么相当于 Linux 中的 Win32 消息泵?

C++ 模板参数作为引用左值