【问题标题】:n-bit signed number where n is not a power of 2n 位有符号数,其中 n 不是 2 的幂
【发布时间】:2016-07-18 21:31:01
【问题描述】:

在 C 或 C++ 中是否可以有例如 6 位有符号整数或 11 位有符号整数(或任何 n 位整数,其中 n != 2^x)?

【问题讨论】:

  • 没有类似的“内置”类型,但是,您可以模拟它们。
  • 查看<cstdint> 获取列表
  • @AndyG:实际上相反是正确的。 C 不要求特定的位宽。已经存在并且仍然存在例如24 位整数和chars。没有少于 8 位的。
  • 这与机器架构相关。如果机器的基本可寻址内存单元是 6 位宽,则 char 类型将是 6 位宽,但您可以像在“8 位”机器上一样声明 char; int 和 long 等也是如此。编译器会透明地处理这个问题。会改变的是这些类型的范围。如果您需要模拟这样的机器,则必须在具有 8 位基本内存可寻址单元的机器上自行实现。
  • @Olaf 好吧,任何少于 8 位的都不是 C,不是 C++,因为 C 和 C++ 都需要至少 8 位,但我确实记得我读过有关实际实现的内容更窄的文章char 但在其他方面非常类似于 C。

标签: c++ c integer bit


【解决方案1】:

当然可能 C 或 C++ 实现可以提供像这样大小的类型,但大多数实现不会提供像这样大小的内置类型,因为 (1)遇到它们并且 (2) 大多数处理器不支持对此类类型的直接操作。

如果您尝试将这些整数用作二进制标志组,请考虑使用 std::bitset 作为其他答案的建议。这甚至可能是一个更好的选择,因为它明确表明您正在使用一组标志。例如:

std::bitset<6> bits; // Six independent bit flags
bits[3] = true;      // Set the third flag

如果您尝试将它们用作实际的整数类型,仅受它们使用的位数限制,请考虑使用位域,如下所示:

struct uint6_t {
    uint64_t value : 6; // 6 bits, unsigned
};
struct int6_t {
    int64_t value : 6;  // 6 bits, signed
};

然后您可以将uint6_t 的value 字段用作六位整数。这仅适用于小于您在位域内使用的基础类型的大小的大小,该大小适用于 6 或 11 等大小,但不适用于 137 或 271 等大小。请注意 - 这些对象的实际大小将由于编译器引入了填充位,可能不是 6 位,但它们仍然会像 6 位整数一样工作。

显然 C++ 模板允许您执行以下操作:

template <unsigned int NumBits> struct uint {
    uint64_t data : NumBits;
};
template <unsigned int NumBits> struct Int {
    int64_t data : NumBits;
};

uint<6> value;
value.data = 0; // Or other uses

Int<6> value;
value.data = -1; // Or other uses

编辑:根据您正在尝试做的事情,您似乎正在寻找这样的东西:

uint<6> value;
value.data = -3;
std::cout << value.data << std::endl; // Prints 3

【讨论】:

  • 好方法,但是您将如何解决 OP 问题中的 signed 部分?会不会有些操作需要重载?
  • 我真正想要实现的是:std::bitset&lt;8&gt; n(-3); std::cout&lt;&lt; static_cast&lt;signed int&gt;(n.to_ulong()); // this is NOT -3 but 253 but I would love it to be -3
  • @templatetypedef 嗯,就这么简单。酷。
  • @carobnodrvo 答案已更新以解决您正在尝试做的事情。
  • 这篇文章的最后一次更新解决了我的问题。谢谢!
【解决方案2】:

您可以使用位域来模拟:

struct int6_t{
    int32_t intPart : 6; // 6 bit integer
}

int_6_t mySilly6bitInt;
mySilly6bitInt.intPart = 5;

【讨论】:

  • 这里需要reserved字段吗?
  • 而不是int32_t,推荐signed int。 int 未定义为 int32_t。
  • @templatetypedef 否,但它描述了 int 的其余部分,通常用作位域中的占位符,以了解剩余的类型。
  • @templatetypedef 对不起,我在考虑工会,你是对的,没有必要。
  • 请查看我对@templatetypedef 帖子的评论。
【解决方案3】:

C 和 C++ 都要求一个字节 unsigned char 至少为 8 位。但是没有上限,也没有二次幂的限制。所以原则上CHAR_BIT(每字节的位数)可以是例如10.

这主要是为了向后兼容。在早期,有基于例如的计算机。 12-bit bytes。为了迎合现代 8 位系统,C99 引入了 stdint.h 标头,该标头提供的类型如果受支持,则保证为 8 位的倍数。

在实践中,您可以模拟具有任意位数的类型,但会产生一些运行时开销。

【讨论】:

    猜你喜欢
    • 2011-11-16
    • 2016-11-14
    • 2012-11-30
    • 2011-04-21
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    • 2022-11-18
    相关资源
    最近更新 更多