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 数组
谢谢
【问题讨论】:
使用<limits.h>
并计算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 <limits>
才能得到这个,您会注意到here 这给出了与 Thomas 的答案相同的值(同时也可以推广到其他原始类型)
作为参考(你在我回答后改变了你的问题),给定程序中给定类型的每个整数(例如,unsigned
)大小完全相同。
您现在要问的不是整数的 size 位,因为它永远不会改变,而是最高位是否已设置。您可以使用
进行简单的测试bool isTopBitSet(uint32_t v)
return v & 0x80000000u;
(如果您想推广到除 uint32_t
之外的无符号 T,请将无符号十六进制文字替换为 T1 << (std::numeric_limits<T>::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<bit_size<int>() >= 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 << 32
是潜在的问题。
不,这显然是个问题。
@user3528438 1UL << 32
不是问题,如果unsigned long
异常宽于 32 位。
不,不是。但是我将代码更改为也可以在带有sizeof(unsigned long) < 64
的奇异系统上工作。 ;-
@user3528438:具体来说,Visual Studio(用于编译几乎所有 Windows 程序的编译器)在为 64 位机器编译时使用 32 位长。在为 64 位机器编译时,Clang 和 G++ 都使用 64 位长。 long
是一种语言,所以重要的是编译器,而不是硬件。以上是关于C++ - 以整数位获取大小的主要内容,如果未能解决你的问题,请参考以下文章