使用SizeOf获得两个最大功率

Using sizeof to get maximum power of two

本文关键字:两个 大功率 SizeOf 使用      更新时间:2023-10-16

在C/C 中是否有一种方法可以使用SizeOf Operator来计算由某些数据类型表示的两个最大功率?

例如,说我有一个unsigned short int。它的值可以介于065535之间。因此,unsigned short int可以包含的两个的最大功率是32768

我将此unsigned short int传递给一个函数,目前(目前)和算法看起来像这样:

if (ushortParam > 32768) {
    ushortParam = 32768; // Bad hardcoded literals
}

但是,将来,我可能想更改变量类型以结合两个的较大功能。是否有使用SizeOf()的独立公式可以实现以下操作:

if (param > /*Some function...*/sizeof(param) )
{
    param = /*Some function...*/sizeof(param);
}

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

设置该参数大小的变量中最重要的位置将给出您是2的最高功率。

1 << (8*sizeof(param)-1)

what:

const T max_power_of_two = (std::numeric_limits<T>::max() >> 1) + 1;

获得以某个整数类型表示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 %dn",max);
  printf("The maximum representable power of 2 is %dn",mpow2);
  return 0;
}

这应该始终起作用,因为始终定义了正整数的正确转移。从标准C节引用6.5.7.5(位移动运算符):

e1 >> e2 的结果是 e1 右切换 e2 bit位置。如果 e1 具有未签名的类型,或者 e1 具有签名类型和非负类型 价值,结果的价值是商人不可或缺的一部分 e1 除以数量,2升至power e2

如果强制使用sizeof,则可以使用:

1 << (CHAR_BIT*sizeof(param)-1)

对于无符号整数类型和:

1 << (CHAR_BIT*sizeof(param)-2)

用于签名的整数类型。仅在整数类型的情况下,上面的行才能工作。标准c的一部分确保这些线路工作在第6.2.6.2节中。特别是:

对于>未签名的char 以外的未签名整数类型 对象表示应分为两组:价值位和 填充位(不需要后者)。如果有n 价值位,每个位应代表1之间2的不同功率 和2n-1,以便该类型的物体能够 使用纯二进制代表0到2n -1的值 表示;这应称为价值表示。

保证第一种工作方法:

对于签名的整数类型,对象表示的位应 分为三组:价值位,填充位和标志 少量。不需要任何填充片;应该有一个 签名位。

...

签名整数类型的有效(非陷阱)对象表示 符号位为零的地方是有效的对象表示 相应的无符号类型,应表示相同的值。

解释了为什么第二行给出正确的答案。

所接受的答案可能会在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的功率少,并且设置了所有值位。以上表达式导致设置最高位,这是类型可以代表的2的最大功率。

http://c0x.coding-guidelines.com/6.2.6.2.html

6.2.6.2整数类型

593对于未签名的整数类型以外的非符号char以外的其他类型,对象表示的位应分为两组:值位和填充位(不需要后者)。

594如果有n个值位,则每个位应表示1和2^(n -1)之间的2个功率,以便该类型的对象应能够表示0到2^n - 的值1使用纯二进制表示;

595这应称为值表示。

596任何填充位的值都未指定。