0

例如,如果我们有一个我们可能不知道大小的无符号整数类型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 来确定实际类型)

4

4 回答 4

4

您可以只使用中定义的常量<limits.h>

#include <limits.h>

size_t maximal = SIZE_T_MAX;
ssize_t smaximal = SSIZE_MAX;
于 2017-06-16T21:32:38.367 回答
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
}
于 2017-06-16T21:48:44.500 回答
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;

或者,我们可以使用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;
于 2017-06-16T22:55:26.037 回答
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)
于 2017-06-16T22:37:15.733 回答