哪些固定宽度整数类型可用

时间:2016-02-03 18:09:57

标签: c c-preprocessor primitive-types fixed-width

所以我试图创建一个使用固定宽度整数的算法的实现。话虽这么说,我想使用可用的最大尺寸,同时需要知道其中的位数,因为算法依赖于位移。

我想要一种方法,最好是通过预处理器,来确定最大整数类型的宽度(目前我正在使用来自uintmax_t的{​​{1}}),但如果没有我可以彻底实现这个,如果我知道编译器定义/支持的固定宽度类型。

我在我的PC上发现了一个旧程序,我有stdint.h的预处理器指令,这是可以通过的,但我不知道这些将在何处定义,或者在什么标准下。

总而言之,如果有人知道计算#ifdef __INT64_TYPE__中的位数的方法,那就完美了,但是我从哪里得到uintmax_t失败了?

2 个答案:

答案 0 :(得分:2)

  

如果有人知道计算uintmax_t中的位数的方法,那就完美了,但是我没有从哪里获得 INT64_TYPE

要计算无符号类型中的位数很容易。设置为-1并计算移位数直到0。

int bc_uintmax_t(void) {
  int bc = 0;
  uintmax_t x = -1;
  while (x) {
    x %= 2;
    bc++;
  }
  return bc;
}

portable 在编译时检测uintmax_t中的位数更难。一个主要障碍是预处理器算法最多只能工作intmax_t。因此,除非做出某些假设,否则便携式解决方案可能无法解决。

当然sizeof (uintmax_t) * CHAR_BIT是类型可能具有的最大可能位宽。然而,可能会出现填充位。

(u)intmax_t中查找uint64_t和精确宽度整数类型,例如<stdint.h>

[编辑]

要在编译时确定常量的位宽,代码可以使用以下代码。注意:使用UINTMAX_MAX时,我不确定此代码的可移植性。

#include <stdio.h>
#include <limits.h>

#define ISGE2_1(x)  ((x) >= 2)
#define ISGE2_2(x)  ((x) >= 4)
#define ISGE2_4(x)  ((x) >= 16)
#define ISGE2_8(x)  ((x) >= 256)
#define ISGE2_16(x) ((x) >= 65536)
#define ISGE2_32(x) ((x)/65536 >= 65536)
#define ISGE2_64(x) ((x)/4294967296 >= 4294967296)
#define ISGE2_128(x) ((x)/18446744073709551616 >= 18446744073709551616)

#define BW_1ORLESS(x)   ((x) ?  1 : 0)
#define BW_2ORLESS(x)   (ISGE2_1(x)  ?  1 + BW_1ORLESS(x/2)                     : BW_1ORLESS(x))
#define BW_4ORLESS(x)   (ISGE2_2(x)  ?  2 + BW_2ORLESS(x/4)                     : BW_2ORLESS(x))
#define BW_8ORLESS(x)   (ISGE2_4(x)  ?  4 + BW_4ORLESS(x/16)                    : BW_4ORLESS(x))
#define BW_16ORLESS(x)  (ISGE2_8(x)  ?  8 + BW_8ORLESS(x/256)                   : BW_8ORLESS(x))
#define BW_32ORLESS(x)  (ISGE2_16(x) ? 16 + BW_16ORLESS(x/65536)                : BW_16ORLESS(x))
#define BW_64ORLESS(x)  (ISGE2_32(x) ? 32 + BW_32ORLESS(x/4294967296)           : BW_32ORLESS(x))
#define BW_128ORLESS(x) (ISGE2_64(x) ? 64 + BW_64ORLESS(x/18446744073709551616) : BW_64ORLESS(x))


#if INTMAX_MAX/4294967296 > 4294967296
  #define BW_65PLUS(x) (ISGE2_128(x) ? BW_129PLUS(x) : BW_128ORLESS(x))
  #define BIT_WIDTH_POSITIVE_VALUE(x) (ISGE2_64(x) ? BW_65PLUS(x) : BW_64ORLESS(x))

#else
  #define BW_33PLUS(x) (ISGE2_64(x)   ? BW_65PLUS(x)  : BW_64ORLESS(x))
  #define BIT_WIDTH_POSITIVE_VALUE(x) (ISGE2_32(x) ? BW_64ORLESS(x) : BW_32ORLESS(x))
#endif

// Do not call BIT_WIDTH_POSITIVE_VALUE with negative values.

应用

#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>

int main() {
  printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(true));
  printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(CHAR_BIT));
  printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(SCHAR_MAX));
  printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(SHRT_MAX));
  printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(INT_MAX));
  printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(LONG_MAX));
  printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(LLONG_MAX));
  printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(INTMAX_MAX));
  printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(UINTMAX_MAX));
  return 0;
}

输出

1
4
7
15
31
31
63
63
64

答案 1 :(得分:0)

我使用了

之类的东西
#if (UINTMAX_MAX > 0xFFFFFFFFFFFFFFF5ULL)