所以我试图创建一个使用固定宽度整数的算法的实现。话虽这么说,我想使用可用的最大尺寸,同时需要知道其中的位数,因为算法依赖于位移。
我想要一种方法,最好是通过预处理器,来确定最大整数类型的宽度(目前我正在使用来自uintmax_t
的{{1}}),但如果没有我可以彻底实现这个,如果我知道编译器定义/支持的固定宽度类型。
我在我的PC上发现了一个旧程序,我有stdint.h
的预处理器指令,这是可以通过的,但我不知道这些将在何处定义,或者在什么标准下。
总而言之,如果有人知道计算#ifdef __INT64_TYPE__
中的位数的方法,那就完美了,但是我从哪里得到uintmax_t
失败了?
答案 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)
等