C中数据类型的最小值和最大值

Sup*_*ing 71 c types

在C中确定数据类型(即int,char.etc)的最小值和最大值的函数是什么?

Mar*_*iot 87

您将要使用limits.h哪个提供以下常量(根据链接的引用):

CHAR_BIT   = number of bits in a char
SCHAR_MIN  = minimum value for a signed char
SCHAR_MAX  = maximum value for a signed char
UCHAR_MAX  = maximum value for an unsigned char
CHAR_MIN   = minimum value for a char
CHAR_MAX   = maximum value for a char
MB_LEN_MAX = maximum multibyte length of a character accross locales
SHRT_MIN   = minimum value for a short
SHRT_MAX   = maximum value for a short
USHRT_MAX  = maximum value for an unsigned short
INT_MIN    = minimum value for an int
INT_MAX    = maximum value for an int
UINT_MAX   = maximum value for an unsigned int
LONG_MIN   = minimum value for a long
LONG_MAX   = maximum value for a long
ULONG_MAX  = maximum value for an unsigned long
LLONG_MIN  = minimum value for a long long
LLONG_MAX  = maximum value for a long long
ULLONG_MAX = maximum value for an unsigned long long
Run Code Online (Sandbox Code Playgroud)

U*_MIN由于显而易见的原因省略了哪里(任何无符号类型的最小值为0).

同样float.h提供限制floatdouble类型:

-FLT_MAX = most negative value of a float
FLT_MAX  = max value of a float
-DBL_MAX = most negative value of a double
DBL_MAX  = max value of a double
-LDBL_MAX = most negative value of a long double
LDBL_MAX = max value of a long double
Run Code Online (Sandbox Code Playgroud)

你应该阅读的文章floats.h细心,虽然floatdouble能保持规定的最低和最高值,但与每个类型可以代表的数据可能不匹配的是什么你想存储的精度.特别是,存储特别大的数字并且附加极小的分数是很困难的.因此,float.h提供了许多其他常量,可帮助您确定a float或a double罐实际上是否代表特定数字.

  • 浮点数的最小值和最大值是多少? (2认同)
  • `SIZE_MAX`(`size_t`的最大大小)是另一个有用的. (2认同)
  • -FLT_MAX和FLT_MAX (2认同)

Gly*_*yph 27

"但是字形",我听到你问,"如果我必须确定最大可能最终会改变的opaque类型的最大值,该怎么办?" 你可以继续说:"如果它是我无法控制的库中的typedef怎么办?"

我很高兴你问,因为我花了几个小时来制作一个解决方案(然后我不得不扔掉,因为它没有解决我的实际问题).

您可以使用此方便的maxof宏来确定任何有效整数类型的大小.

#define issigned(t) (((t)(-1)) < ((t) 0))

#define umaxof(t) (((0x1ULL << ((sizeof(t) * 8ULL) - 1ULL)) - 1ULL) | \
                    (0xFULL << ((sizeof(t) * 8ULL) - 4ULL)))

#define smaxof(t) (((0x1ULL << ((sizeof(t) * 8ULL) - 1ULL)) - 1ULL) | \
                    (0x7ULL << ((sizeof(t) * 8ULL) - 4ULL)))

#define maxof(t) ((unsigned long long) (issigned(t) ? smaxof(t) : umaxof(t)))
Run Code Online (Sandbox Code Playgroud)

您可以像这样使用它:

int main(int argc, char** argv) {
    printf("schar: %llx uchar: %llx\n", maxof(char), maxof(unsigned char));
    printf("sshort: %llx ushort: %llx\n", maxof(short), maxof(unsigned short));
    printf("sint: %llx uint: %llx\n", maxof(int), maxof(unsigned int));
    printf("slong: %llx ulong: %llx\n", maxof(long), maxof(unsigned long));
    printf("slong long: %llx ulong long: %llx\n",
           maxof(long long), maxof(unsigned long long));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以在这些宏的前面放一个'(t)',这样它们就会给出您所询问的类型的结果,而且您​​不必进行强制转换以避免出现警告.

  • 所有这些 8ULL 的常量可能都应该是 CHAR_BIT。 (2认同)
  • `smaxof(t)` 假设 1) 无填充,2) 8 位为一个“字节”。合理的假设,但 C 未指定。 (2认同)

Exp*_*r09 6

任何无符号整数类型的最大值:((t)~(t)0)

任何有符号整数类型的最大值:如果您有一个类型为t的无符号变量,(~(t)0)将为您提供所需的最快结果(请参阅下面引用的Linux内核源代码中的示例).否则,你应该使用t.

任何有符号整数类型的最小值:您必须知道机器的有符号数字表示.大多数机器使用2的补码,因此unsigned int适合您.

要检测你的机器是否使用2的补数,检测是否((t)~0U)t代表同样的事情.所以,结合以上:

(-(((1ULL<<(sizeof(t)*CHAR_BIT-2))-1)*2+1)-(((~(t)0U)==(t)(-1)))
Run Code Online (Sandbox Code Playgroud)

将为您提供任何有符号整数类型的最小值.(实际上,如果你知道2的补码表示,还有其他的表示形式.例如,unsigned int应该相当于unsigned int.)

例如:(〜(size_t)0)为您提供size_t的最大值.(猜猜看,这是SIZE_MAX在Linux内核源代码中的 #defined .)

但有一点需要注意:所有这些表达式都使用类型转换,因此不适用于预处理器条件(#if ... #elif ... #endif等).