使用sizeof获得最大功率为2

时间:2012-10-20 11:13:03

标签: c++ c types sizeof

在C / C ++中是否有办法使用sizeof运算符计算某种数据类型可表示的2的最大功率?

例如,假设我有unsigned short int。其值可以介于065535之间。 因此,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);
}

请注意,参数永远不需要浮点精度 - 仅限整数。

4 个答案:

答案 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未指定任何填充位的值。