在C / C ++中是否有办法使用sizeof运算符计算某种数据类型可表示的2的最大功率?
例如,假设我有unsigned short int
。其值可以介于0
和65535
之间。
因此,unsigned short int
可以包含的最大2的幂是32768
。
我将此unsigned short int
传递给一个函数,我(目前)和算法看起来像这样:
if (ushortParam > 32768) {
ushortParam = 32768; // Bad hardcoded literals
}
但是,在将来,我可能想要更改变量类型以包含更大的2的幂。是否存在使用sizeof()的类型无关公式,可以实现以下目的:
if (param > /*Some function...*/sizeof(param) )
{
param = /*Some function...*/sizeof(param);
}
请注意,参数永远不需要浮点精度 - 仅限整数。
答案 0 :(得分:4)
设置该参数大小的变量的最高位将为您提供2的最高功率。
1 << (8*sizeof(param)-1)
答案 1 :(得分:3)
怎么样:
const T max_power_of_two = (std::numeric_limits<T>::max() >> 1) + 1;
答案 2 :(得分:2)
要获得某个整数类型可表示的最高2的幂,您可以使用limits.h
而不是sizeof
运算符。例如:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
int main() {
int max = INT_MAX;
int hmax = max>>1;
int mpow2 = max ^ hmax;
printf("The maximum representable integer is %d\n",max);
printf("The maximum representable power of 2 is %d\n",mpow2);
return 0;
}
这应始终有效,因为始终定义正整数的右移。引自标准C部分6.5.7.5(按位移位运算符):
E1 的结果&gt;&gt; E2 是 E1 右移 E2 位位置。如果 E1 具有无符号类型或 E1 具有签名类型和非负数 值,结果的值是商的整数部分 E1 除以数量,2增加到幂 E2 。
如果强制使用sizeof
,您可以使用:
1 << (CHAR_BIT*sizeof(param)-1)
表示无符号整数类型,并且:
1 << (CHAR_BIT*sizeof(param)-2)
用于有符号整数类型。上面的行仅适用于整数类型没有填充位的情况。确保这些线路工作的标准C部分见6.2.6.2节。特别是:
对于 unsigned char 以外的无符号整数类型,其位数为 对象表示应分为两组:值位和 填充位(不需要任何后者)。如果有N. 值位,每个位应表示1之间的不同2的幂 和2N-1,以便该类型的物体能够 使用纯二进制表示0到2N - 1之间的值 表示;这应该被称为价值表示。
保证第一种方法可以工作:
对于有符号整数类型,对象表示的位应为 分为三组:值位,填充位和符号 位。不需要任何填充位;应该只有一个 标志位。
...
有符号整数类型的有效(非陷阱)对象表示 符号位为零的地方是有效的对象表示 相应的无符号类型,并且应代表相同的值。
解释为什么第二行给出了正确答案。
答案 3 :(得分:0)
接受的答案可能适用于Posix平台,但不是通用的C / C ++。它假设CHAR_BIT是8,没有指定类型,并假定该类型没有填充位。
以下是任何/所有无符号整数类型的更通用版本,并且不需要包括任何标头,依赖项等:
#define MAX_VAL(UNSIGNED_TYPE) ((UNSIGNED_TYPE) -1)
#define MAX_POW2(UNSIGNED_TYPE) (~(MAX_VAL(UNSIGNED_TYPE) >> 1))
#define MAX_POW2_VER2(UNSIGNED_TYPE) (MAX_VAL(UNSIGNED_TYPE) ^ (MAX_VAL(UNSIGNED_TYPE) >> 1))
#define MAX_POW2_VER3(UNSIGNED_TYPE) ((MAX_VAL(UNSIGNED_TYPE) >> 1) + 1)
标准,甚至C90,保证将-1转换为无符号类型总是产生类型可以表示的最大值。从那里,上面的所有按位运算符都已明确定义。
http://c0x.coding-guidelines.com/6.3.1.3.html
6.3.1.3有符号和无符号整数
682当整数类型的值转换为_Bool以外的另一个整数类型时,如果该值可以用新类型表示,则它不会改变。
683 否则,如果新类型是无符号的,则通过重复加或减一个可以在新类型中表示的最大值来转换该值,直到该值在新类型的范围内为止强>
684否则,新类型已签名且值无法在其中表示;
685结果是实现定义的,或者引发实现定义的信号。
无符号类型的最大值比2的幂小1并且设置了所有值位。上面的表达式导致单独设置最高位,这是该类型可以表示的最大2的幂。
http://c0x.coding-guidelines.com/6.2.6.2.html
6.2.6.2整数类型
593对于unsigned char以外的无符号整数类型,对象表示的位应分为两组:值位和填充位(不需要任何后者)。
594如果有N个值位,则每个位应表示1和2 ^(N-1)之间的2的不同幂,因此该类型的对象应能够表示0到2 ^ N的值 - 1使用纯二进制表示;
595这将被称为价值表示。
596未指定任何填充位的值。