C++ - 以整数位获取大小

Posted

技术标签:

【中文标题】C++ - 以整数位获取大小【英文标题】:C++ - Getting size in bits of integer 【发布时间】: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. 你能帮我吗?谢谢 【参考方案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,请将无符号十六进制文字替换为 T1 &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 是一种语言,所以重要的是编译器,而不是硬件。

以上是关于C++ - 以整数位获取大小的主要内容,如果未能解决你的问题,请参考以下文章

C++ - 从结束地址获取函数的起始地址/获取函数的大小

如何获取 C++ 类成员向量的大小?

C++中怎样获取一个文件的大小,怎样判断一个文件是不是为空(文件存在,但是没有内容)

C++学习(四三八)java获取文件大小

C++ 如何从动态分配中获取数组大小?

通过 C++ 获取 micro SD 卡的大小