C++ 构造有符号位域

C++ 构造有符号位域,c++,bit-fields,C++,Bit Fields,下面,我构建了一个使用位字段的代码的小示例。 在实现比较运算符时,我注意到它没有按预期工作。问题是-1似乎并不小于1 在考虑了一段时间后,我觉得构造函数中的掩蔽有问题 我在那里添加了“aValue&MAX_VALUE”,因为否则编译器会给出转换警告。但是,首先使用MAX_值进行掩蔽,然后将其转换为int32_t并不能给出正确的结果 有人知道我怎么解决这个问题吗? 当我编写minusOne.v=-1时,似乎确实得到了预期的结果。但我不确定如何在构造函数中编写它(而不会得到转换警告) #包括 #包括

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

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

我在那里添加了“aValue&MAX_VALUE”,因为否则编译器会给出转换警告。但是,首先使用MAX_值进行掩蔽,然后将其转换为int32_t并不能给出正确的结果

有人知道我怎么解决这个问题吗? 当我编写
minusOne.v=-1时,似乎确实得到了预期的结果。但我不确定如何在构造函数中编写它(而不会得到转换警告)

#包括
#包括
使用名称空间std;
结构int27\t
{
国际电视台:27;

constexpr static int32_t MIN_VALUE=-(1L布尔运算对有符号类型不起作用。 您只需在构造函数中删除符号即可

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

  • 不要在有符号类型上使用二进制算术。只是不要这样做。如果真的需要,算术地转换为
    无符号的
    (乘以-1并注意溢出),做点什么,然后返回到有符号的算术地
  • 您依赖于符号数字的某种表示形式。据我所知(关于符号类型是C99),该语言提供三种不同的表示形式:符号和大小、一个补码和两个补码,参见ISO/IEC 9899:TC2§6.2.6.2-2
  • 假设2的补码对几乎所有最近的平台都适用,那么您的
    MIN\u值
    将关闭1
  • 请不要使用位字段。几乎任何最新的体系结构都会将其扩展到某些字大小的类型。您可能只会遇到麻烦,因为签名溢出是未定义的行为。因此,以这种方式限制签名类型的范围没有意义

  • 布尔运算在有符号类型上不起作用。 您只需在构造函数中删除符号即可

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

  • 不要在有符号类型上使用二进制算术。只是不要这样做。如果真的需要,算术地转换为
    无符号的
    (乘以-1并注意溢出),做点什么,然后返回到有符号的算术地
  • 您依赖于符号数字的某种表示形式。据我所知(关于符号类型是C99),该语言提供三种不同的表示形式:符号和大小、一个补码和两个补码,参见ISO/IEC 9899:TC2§6.2.6.2-2
  • 假设2的补码对几乎所有最近的平台都适用,那么您的
    MIN\u值
    将关闭1
  • 请不要使用位字段。几乎任何最新的体系结构都会将其扩展到某些字大小的类型。您可能只会遇到麻烦,因为签名溢出是未定义的行为。因此,以这种方式限制签名类型的范围没有意义

  • 这里真的没有理由使用位域。在现代平台上,这种结构无论如何都会被舍入到32位。同样,掩蔽和不兼容的方式,符号位会被撕掉。@塔德曼,我理解用符号位的最大值撕裂来掩蔽。但我如何修复它?用掩蔽值进行掩蔽会导致转换警告ing。我认为这里的@kamajii有一些很好的建议,我鼓励你遵循它。这里真的没有理由使用位域。在现代平台上,这种结构无论如何都会被舍入到32位。而且掩蔽和不兼容,符号位会被撕掉。@tadman,我理解用符号bi的最大值撕裂掩蔽t、 但我该如何解决这个问题呢?使用掩码值屏蔽会导致转换警告。我认为@kamajii这里有一些很好的建议,我鼓励您遵循。读到这篇文章,我所做的看起来非常糟糕,我会考虑在没有位字段的情况下采取不同的方法。我的目标不是获得良好的性能,而是模拟不同的性能对位数有一定限制的计算设备(因此是模拟,而不是性能)。但这对你的论点来说并不重要。我会考虑如何改变它。你确定我的
    MIN_值是一次性的吗?对我来说似乎是正确的,应该还有一个负值。读到这篇文章,我做的事情看起来很糟糕,我会考虑在没有位字段的情况下采取不同的方法。我的目标是不获得良好的性能性能,但要模拟不同的设备,该设备在计算时对位数有一定的限制(因此是模拟,而不是性能)。但这对你的论点来说并不重要。我会考虑如何更改它。你确定我的
    MIN\u值
    是一次性的吗?我认为这是正确的,应该还有一个负值。
    #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