【问题标题】:Weird Data Types - C++奇怪的数据类型 - C++
【发布时间】:2021-09-30 05:57:45
【问题描述】:

我知道这听起来像一个愚蠢的问题,但我想知道是否有可能以任何方式制作这样的自定义变量大小,而不是使用普通的 8、16、32 和 64 位整数:

uint15_t var; //as an example

我在网上做了一些研究,但没有发现适用于所有尺寸的东西(只有stuff,比如 12 位和 24 位)。 (我还想知道位域是否也适用于其他数据大小)。

是的,我知道你可以使用一个 16 位整数来存储一个 15 位的值,但我只是想知道是否可以这样做。

如何制作和实现自定义整数大小?

【问题讨论】:

  • 可能是std::bitset<15> 之类的?但是,您不能更改基础数据类型。
  • This answer 到链接的问题看起来是这个问题的一个很好的答案。你为什么说你发现“没有任何东西适用于所有尺寸”?你想让你的新类型做一些特别的事情吗?
  • @anatolyg 为了清晰起见,我只是想知道它是否适用于所有尺寸
  • “全部”是什么意思?是例如100000 是您要支持的示例大小吗?
  • @anatolyg 计算机可以使用的东西

标签: c++ uint


【解决方案1】:

在结构或类中,可以使用位域功能为成员变量声明所需大小的整数:

unsigned int var : 15;

...它的 CPU 效率不是很高(因为编译器必须在对该变量的大多数访问中生成按位运算),但它会为您提供所需的 15 位行为。

【讨论】:

【解决方案2】:

为了能够将您的位域 int 用作普通 int 但仍能获得 15 位 int 的行为,您可以这样做:

#include <cassert>
#include <utility>

template<typename type_t, std::size_t N>
struct bits_t final
{
    bits_t() = default;
    ~bits_t() = default;

    // explicitly implicit so it can convert automatically from underlying type
    bits_t(const type_t& value) :
        m_value{ value }
    {
    };

    // implicit conversion back to underlying type
    operator type_t ()
    {
        return m_value;
    }

private:
    type_t m_value : N;
};


int main()
{
    bits_t<int, 15> value;
    value = 16383;  // 0x3FFF
    assert(value == 16383);
    
    // overflow now at bit 15 :)
    value = 16384; // 0x4000, 16th bit is set.
    assert(value == -16384);

    return 0;
}

【讨论】:

    【解决方案3】:

    位域功能可以解决问题...

    uint32_t customInt : 15;
    

    【讨论】:

      【解决方案4】:

      您可以尝试使用位域,就像许多人提到的那样。但是,位域没有正确的类型。如果您想让任意大小的整数面向对象,可以将位域填充到模板中:

      template <int size> struct my_uint
      {
          uint32_t value: size;
      };
      typedef my_uint<13> uint13_t; // some people use "using" syntax to do this
      typedef my_uint<14> uint14_t;
      typedef my_uint<15> uint15_t;
      

      但是,现在您丢失了算术运算符,您必须自己实现(重载)它们。你必须问自己很多问题,关于你真正想用这些新类型做什么:

      • 是否要重载 +、* 等运算符?哪些?
      • 您想支持数组吗?
      • 您希望支持的最大尺寸是多少?在我的示例中,它是 32。
      • 是否要支持隐式构造函数,例如uint15_t(uint32_t)?
      • 如何支持溢出?

      没有办法让你的新类型表现得像内置类型——你可以接近但不能完全做到。也就是说,如果你编写了一个使用uint15_t 的大程序,然后你决定切换到uint16_t,那么uint16_t 是一个内置类型会引起细微的变化(例如,考虑关于@987654321 的规则@)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-05-31
        • 2021-12-04
        • 2016-10-31
        • 2016-01-14
        • 2017-01-06
        • 2020-04-27
        • 1970-01-01
        相关资源
        最近更新 更多