C 大小未知的有符号整数类型的最大正值

C 大小未知的有符号整数类型的最大正值,c,signed-integer,C,Signed Integer,如果我们有一个不知道大小的无符号整数类型,例如size\u t,那么我们可以相对简单地通过如下方式获得它所能容纳的最大值: size_t maximal = -1; 对于有符号整数类型是否有类似的技术,例如ssize\u t?例如: ssize_t smaximal = ???; 注意,可能没有相应的无符号类型,例如time\t(暂时忽略它甚至可能不是整数) [编辑1]使用大小\u t/ssize\u t/时间\u t只是为了说明,我正在寻找一个没有XXX\u MAX帮助的通用解决方案 [E

如果我们有一个不知道大小的无符号整数类型,例如
size\u t
,那么我们可以相对简单地通过如下方式获得它所能容纳的最大值:

size_t maximal = -1;
对于有符号整数类型是否有类似的技术,例如
ssize\u t
?例如:

ssize_t smaximal = ???;
注意,可能没有相应的无符号类型,例如
time\t
(暂时忽略它甚至可能不是整数)

[编辑1]使用大小\u t/ssize\u t/时间\u t只是为了说明,我正在寻找一个没有XXX\u MAX帮助的通用解决方案

[EDIT 2]这似乎有效,但我不确定这是否“只是运气”:


(如果
foo_int_type
的实际类型是通过一些可怕的预处理器错误确定的,我不想复制)

您可以使用
中定义的常量:

#包括
最大尺寸=最大尺寸;
ssize_t smaximal=ssize_MAX;

您可以使用
中定义的常量:

#包括
最大尺寸=最大尺寸;
ssize_t smaximal=ssize_MAX;

对于签名类型AFAIK,没有简单、完全可移植的方法。 您可以将
*\u MAX
宏放在
\u 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
}
#定义Z_max(X)\
_通用(X\
char:char_MAX\
\
签名字符:SCHAR_MAX\
简称:SHRT_MAX\
int:int_MAX\
朗:朗·马克斯\
朗朗:朗朗·马克斯\
\
未签名字符:UCHAR_MAX\
未签名短消息:USHRT_MAX\
无符号整数:UINT_MAX\
未签名长:ULONG_MAX\
未签名的long long:ULLONG_MAX\
)                                                                      \
#包括
#包括
int main()
{
printf(“%d\n”,Z_max(1));//在我的系统上打印2147483647
}

对于签名类型AFAIK,没有简单、完全可移植的方法。 您可以将
*\u MAX
宏放在
\u 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
}
#定义Z_max(X)\
_通用(X\
char:char_MAX\
\
签名字符:SCHAR_MAX\
简称:SHRT_MAX\
int:int_MAX\
朗:朗·马克斯\
朗朗:朗朗·马克斯\
\
未签名字符:UCHAR_MAX\
未签名短消息:USHRT_MAX\
无符号整数:UINT_MAX\
未签名长:ULONG_MAX\
未签名的long long:ULLONG_MAX\
)                                                                      \
#包括
#包括
int main()
{
printf(“%d\n”,Z_max(1));//在我的系统上打印2147483647
}

我找不到表达式,但找到了使用循环的函数

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

如果您不知道类型的大小,并且没有库支持来确定最大值,那么可以利用二进制表示法

表示有符号整数的常用方法是使用。2的补码中有符号类型的最大值是0后跟1(
011111…111

现在如何获得该值?我们需要从一个已知的值开始,并使用位运算来获得所需的结果。已知值:

  • 0=
    0000…000
  • 1=
    0000…001
  • 等等
没什么帮助。但是

  • -1=
    1111…111
让我们很接近。现在我们不知道常数FOO_MIN==
1000…000
,我们可以用它来
XOR()
和-1,所以我们可以求助于位移位。如果我们将
-1
右移一位,并确保
0
将被移入,我们将得到所需的值

在C语言中,负值的右位移位是实现定义的,因此它既可以是算术移位(在
1
中移位)也可以是逻辑移位(在
0
中移位),而且大部分是算术移位(请参阅),因此我们需要在移位之前将值类型转换为足够大的无符号类型

下面是:

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

如果您不知道类型的大小,并且没有库支持来确定最大值,那么可以利用二进制表示法

表示有符号整数的常用方法是使用。2中有符号类型的最大值
#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;
#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;