如果我们有一个无符号整数类型,我们可能不知道它的大小,例如size_t
,那么我们可以相对简单地得到它可以容纳的最大值:
size_t maximal = -1;
是否有类似的签名整数类型的技术,例如ssize_t
?如:
ssize_t smaximal = ???;
注意,可能没有相应的无符号类型,例如time_t
(暂时忽略它甚至可能不是整数)。
[编辑1] 使用size_t / ssize_t / time_t仅用于说明目的,我正在寻找没有XXX_MAX帮助的一般解决方案。
[编辑2] 这似乎有效,但我不确定这是不是"只是运气":
#include "foo_library_with_no_max_macros_because_they_are_dumb.h"
foo_int_type foo = (((unsigned)-1) >> 1);
(其中foo_int_type
的实际类型是通过一些可怕的预处理器goop来确定的,我不想复制)
答案 0 :(得分:3)
您可以使用<limits.h>
中定义的常量:
#include <limits.h>
size_t maximal = SIZE_T_MAX;
ssize_t smaximal = SSIZE_MAX;
答案 1 :(得分:1)
对于签名类型AFAIK,没有简单,完全可移植的方式。
您可以将*_MAX
宏放在_Generic
宏中,然后您就不必再担心它们了。
#define Z_max(X) \
_Generic(X, \
char: CHAR_MAX, \
\
signed char: SCHAR_MAX, \
short: SHRT_MAX, \
int: INT_MAX, \
long: LONG_MAX, \
long long: LLONG_MAX, \
\
unsigned char: UCHAR_MAX, \
unsigned short : USHRT_MAX, \
unsigned int: UINT_MAX, \
unsigned long: ULONG_MAX, \
unsigned long long: ULLONG_MAX \
) \
#include <stdio.h>
#include <limits.h>
int main()
{
printf("%d\n", Z_max(1)); //prints 2147483647 on my system
}
答案 2 :(得分:1)
如果您不知道类型的大小并且没有库支持来确定最大值,则可以求助于利用二进制表示。
表示有符号整数的常用方法是使用the Two's complement。二进制补码中带符号类型的最大值为零,后跟一个(011111...111
)。
现在如何获得这个价值?我们需要从已知值开始并使用按位运算来获得所需的结果。已知值:
0000...000
0000...001
没有真正的帮助。但是
1111...111
让我们相当亲密。现在我们不知道常量FOO_MIN == 1000...000
我们可以使用-1 XOR()
,因此我们可以求助于位移。如果我们将-1
向右移一位并确保将0
移入,我们将获得所需的值。
在C中,负值的右移位是实现定义的,因此它可以是算术(在1
中移位)和逻辑(在0
中移位)移位,并且主要是是算术的(见this answer),所以我们需要在转换之前将值转换为足够大的无符号类型。
这里是:
#include <stdint.h>
#include "foo_library_with_no_max_macros_because_they_are_dumb.h"
foo_int_type foo = ((uint64_t)((foo_int_type)-1)) >> 1;
或者,我们可以使用sizeof()
来生成FOO_MIN
。
#include "foo_library_with_no_max_macros_because_they_are_dumb.h"
foo_int_type foo_min = ((foo_int_type)1) << (8 * sizeof(foo_min) - 1);
foo_int_type foo = ((foo_int_type)-1) ^ foo_min;
答案 3 :(得分:0)
我无法找到表达式,但是使用循环
的函数#define integer int /* change as required */
integer max()
{
integer x=0x7f;
size_t n=sizeof(integer)-1;
while(n--) {
x <<= 8; /* may create spurious warning for integer=signed char */
x |= 0xff;
}
return x;
}
或宏
#define MaxSignedInteger(integer) \
(integer)(sizeof(integer)==1? 0x7f : \
sizeof(integer)==2? 0x7fff : \
sizeof(integer)==4? 0x7fffffff : \
0x7fffffffffffffffll)