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>
.
在
[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>
.
在
[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.
等等