【问题标题】:C++ - Getting size in bits of integerC++ - 以整数位获取大小
【发布时间】:2015-05-30 20:56:12
【问题描述】:

我需要知道一个整数是否为 32 位长(我想知道它是否正好是 32 位长(8 个十六进制字符)。我如何在 C++ 中实现这一点?我应该使用十六进制表示还是用 unsigned int 吗?

我的代码如下:

mistream.open("myfile.txt");

if(mistream)
{
    for(int i=0; i<longArray; i++)
    {
        mistream >> hex >> datos[i];        
    }
}

mistream.close();

其中 mistream 是 ifstream 类型,而 datos 是 unsigned int 数组

谢谢

【问题讨论】:

  • 使用&lt;limits.h&gt;并计算sizeof(int)*CHAR_BIT或测试INT_MAX/INT_MIN
  • 我不确定您是否想知道int 类型的变量在您的平台中使用了多少位,或者表示特定整数值需要多少位。在整数中可能需要 32 位,但它只需要 1 位来表示值 0。
  • 一种不可移植的方法是使用非标准的内在函数。大多数机器都有计算前导零或前导冗余符号位的指令。
  • 明确一点:您是否有兴趣知道 type 是 32 位还是 value 介于 power(2,31) and power(2,32)-1 或其他之间?
  • 是的@chux 我有兴趣知道该值是否介于 power(2, 31) 和 power(2, 32) - 1. 你能帮我吗?谢谢

标签: c++ c integer hex ifstream


【解决方案1】:
std::numeric_limits<unsigned>::digits

是一个静态整数常量(或 C++11 中的 constexpr),给出位数(因为无符号存储在基数 2 中,它给出二进制数字)。

您需要#include &lt;limits&gt; 才能得到这个,您会注意到here 这给出了与 Thomas 的答案相同的值(同时也可以推广到其他原始类型)


作为参考(你在我回答后改变了你的问题),给定程序中给定类型的每个整数(例如,unsigned大小完全相同

您现在要问的不是整数的 size 位,因为它永远不会改变,而是最高位是否已设置。您可以使用

进行简单的测试
bool isTopBitSet(uint32_t v) {
  return v & 0x80000000u;
}

(如果您想推广到除 uint32_t 之外的无符号 T,请将无符号十六进制文字替换为 T{1} &lt;&lt; (std::numeric_limits&lt;T&gt;::digits-1))。

【讨论】:

  • 我该如何使用它?我的意思是,我有一个无符号整数,我该如何使用你的方法?
  • @fergaral 你什么意思?您只需要类型,而不需要值本身。
【解决方案2】:

我想知道它是否正好是 32 位长(8 个十六进制字符)

我有兴趣知道该值是否介于 power(2, 31) 和 power(2, 32) - 1 之间

所以你想知道是否设置了高位?然后你可以简单地测试这个数字是否为负:

bool upperBitSet(int x)
{
    return x < 0;
}

对于无符号数,您可以简单地左右移动,然后检查是否丢失数据:

bool upperBitSet(unsigned x)
{
    return (x << 1 >> 1) != x;
}

【讨论】:

    【解决方案3】:

    OP 说“如果它正好是 32 位长(8 个十六进制字符)”,并进一步说“.. 有兴趣知道该值是否介于 power(2, 31) 和 power(2, 32) - 1 之间”。所以它对负 32 位数字有点模糊。

    当然 OP 想根据值而不是类型知道结果。

    bool integer_is_32_bits_long(int x) = 
        // cope with 32-bit int
        ((INT_MAX == 0x7FFFFFFF) && (x < 0)) ||
        // larger 32-bit int
        ((INT_MAX >  0x7FFFFFFF) && (x >= 0x80000000) && (x <= 0xFFFFFFFF));
    

    当然如果int 是16 位的,那么结果总是false

    【讨论】:

      【解决方案4】:

      试试这个:

      #include <climits>
      
      unsigned int bits_per_byte = CHAR_BIT;
      unsigned int bits_per_integer = CHAR_BIT * sizeof(int);
      

      标识符CHAR_BIT 表示char 中的位数。

      sizeof 返回整数占用的字符位置数。

      将它们相乘得到整数的位数。

      【讨论】:

      • CHAR_BITS 的值是多少?我的意思是,确切的价值,或者,如果不是,我怎么能得到它?谢谢
      • 这在实践中有效,但不能保证。该标准允许int 使用 29 位。
      • 宏被命名为CHAR_BIT(单数),定义在climits,而不是cstdint:en.cppreference.com/w/cpp/types/climits
      • 我这样做是这样的:unsigned int bits_per_integer = CHAR_BITS * sizeof(myarray[i]),但它总是返回 32。我做错了什么?
      • 根据@5gon12eder 的评论编辑。
      【解决方案5】:

      正如@chux 在评论中已经暗示的那样,您可以使用sizeof 运算符和CHAR_BIT 宏常量的组合。前者告诉您(在编译时)其参数类型的大小(以sizeof(char) aka 字节为单位的倍数)。后者是字节的位数(通常为 8)。

      您可以很好地将其封装到函数模板中。

      #include <climits>   // CHAR_BIT
      #include <cstddef>   // std::size_t
      #include <iostream>  // std::cout, std::endl
      
      template <typename T>
      constexpr std::size_t
      bit_size() noexcept
      {
        return sizeof(T) * CHAR_BIT;
      }
      
      int
      main()
      {
        std::cout << bit_size<int>() << std::endl;
        std::cout << bit_size<long>() << std::endl;
      }
      

      在我的实现中,它输出 32 和 64。

      由于该函数是constexpr,因此您可以在静态上下文中使用它,例如static_assert&lt;bit_size&lt;int&gt;() &gt;= 32, "too small");

      【讨论】:

        【解决方案6】:

        最简单的方法可能是检查第 32 位是否已设置:

        bool isReally32bitsLong(uint32_t in) {
          return (in >> 31)!=0;
        }
        
        bool isExactly32BitsLong(uint64_t in) {
          return ((in >> 31)!=0) && ((in >> 32) == 0);
        }
        

        【讨论】:

        • 1UL &lt;&lt; 32 是潜在的问题。
        • 不,这显然是个问题。
        • @user3528438 1UL &lt;&lt; 32 不是问题,如果unsigned long 异常宽于 32 位。
        • 不,不是。但是我将代码更改为也可以在带有sizeof(unsigned long) &lt; 64 的奇异系统上工作。 ;-}
        • @user3528438:具体来说,Visual Studio(用于编译几乎所有 Windows 程序的编译器)在为 64 位机器编译时使用 32 位长。在为 64 位机器编译时,Clang 和 G++ 都使用 64 位长。 long 是一种语言,所以重要的是编译器,而不是硬件。
        猜你喜欢
        • 2016-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-29
        • 1970-01-01
        • 1970-01-01
        • 2010-12-09
        • 1970-01-01
        相关资源
        最近更新 更多