如果有人知道计算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;
}
便携在编译时检测uintmax_t 中的位数更难。一个主要的障碍是预处理器算法可能只能工作到intmax_t。因此,除非做出一些假设,否则便携式解决方案可能无法找到。
当然sizeof (uintmax_t) * CHAR_BIT 是该类型可能具有的最大 位宽度。然而可能会出现填充位。
在<stdint.h> 中查找(u)intmax_t 和精确宽度整数类型,如uint64_t。
[编辑]
要在编译时确定常量的值位宽度,代码可以使用以下代码。注意:对于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