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

时间:2023-01-29 20:28:26

So I'm trying to create an implementation of an algorithm that uses fixed-width integers. That being said I want to use the largest size available, and at the same time need to know the number of bits in it, as the algorithm relies on bit shifting.

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

I would like a way, preferably via pre-processor, to determine the width of the largest integer type (currently I'm using uintmax_t from stdint.h), but failing that I could exhaustively achieve this if I know the fixed-width types that are defined/supported by the compiler.

我想要一种方法,最好是通过预处理器,来确定最大整数类型的宽度(目前我正在使用stdint.h中的uintmax_t),但如果我知道固定宽度类型,我就无法完全实现这一点由编译器定义/支持的。

I found an old program on my PC where I have the pre-processor directives of #ifdef __INT64_TYPE__, which would be passable, but I have no idea where these would be defined, or under what standards.

我在我的电脑上发现了一个旧程序,我有#ifdef __INT64_TYPE__的预处理器指令,它可以通过,但我不知道这些将在何处定义,或者在什么标准下。

So to sum up, if anyone knows a way to count the number of bits in uintmax_t, that'd be perfect, but failing that where have I got __INT64_TYPE__ from?

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

2 个解决方案

#1


2  

if anyone knows a way to count the number of bits in uintmax_t, that'd be perfect, but failing that where have I got INT64_TYPE from?

如果有人知道一种计算uintmax_t中位数的方法,那就完美了,但失败的地方我从哪里得到了INT64_TYPE?

To count the number of bit in an unsigned type is easy. Set to -1 and count the number of shift until 0.

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

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

To portable detect the number of bits in uintmax_t at compile time is harder. A chief obstacle is the pre-preprocessor arithmetic may only work up to intmax_t. So unless some assumptions are made, a portable solution may be unfindable.

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

Of course sizeof (uintmax_t) * CHAR_BIT is the maximum possible bit width that type could have. Yet padding bits could occur.

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

Look for (u)intmax_t and Exact-width integer types like uint64_t in <stdint.h>.

中查找(u)intmax_t和Exact-width整数类型,如uint64_t。


[Edit]

[编辑]

To determine the value bit width of a constant at compile time, code could use the following. Note: With UINTMAX_MAX, I am not certain how portable is this code.

要在编译时确定常量的值位宽,代码可以使用以下代码。注意:使用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.

Application

应用

#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;
}

Output

产量

1
4
7
15
31
31
63
63
64

#2


0  

I've used things like

我用过像这样的东西

#if (UINTMAX_MAX > 0xFFFFFFFFFFFFFFF5ULL)

etc.

等等

#1


2  

if anyone knows a way to count the number of bits in uintmax_t, that'd be perfect, but failing that where have I got INT64_TYPE from?

如果有人知道一种计算uintmax_t中位数的方法,那就完美了,但失败的地方我从哪里得到了INT64_TYPE?

To count the number of bit in an unsigned type is easy. Set to -1 and count the number of shift until 0.

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

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

To portable detect the number of bits in uintmax_t at compile time is harder. A chief obstacle is the pre-preprocessor arithmetic may only work up to intmax_t. So unless some assumptions are made, a portable solution may be unfindable.

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

Of course sizeof (uintmax_t) * CHAR_BIT is the maximum possible bit width that type could have. Yet padding bits could occur.

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

Look for (u)intmax_t and Exact-width integer types like uint64_t in <stdint.h>.

中查找(u)intmax_t和Exact-width整数类型,如uint64_t。


[Edit]

[编辑]

To determine the value bit width of a constant at compile time, code could use the following. Note: With UINTMAX_MAX, I am not certain how portable is this code.

要在编译时确定常量的值位宽,代码可以使用以下代码。注意:使用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.

Application

应用

#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;
}

Output

产量

1
4
7
15
31
31
63
63
64

#2


0  

I've used things like

我用过像这样的东西

#if (UINTMAX_MAX > 0xFFFFFFFFFFFFFFF5ULL)

etc.

等等