C语言 C中数据类型的最小值和最大值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2053843/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
min and max value of data type in C
提问by SuperString
What is the function to determine the min and max possible of value of datatypes (i.e, int, char.etc) in C?
确定 C 中数据类型(即 int、char.etc)的最小值和最大值的函数是什么?
回答by Mark Elliot
You'll want to use limits.hwhich provides the following constants (as per the linked reference):
您将要使用limits.hwhich 提供以下常量(根据链接的参考):
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
Where U*_MINis omitted for obvious reasons (any unsigned type has a minimum value of 0).
U*_MIN由于显而易见的原因省略了where (任何无符号类型的最小值为 0)。
Similarly float.hprovides limits for floatand doubletypes:
同样float.h为float和double类型提供限制:
-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
You should read the article on floats.hcarefully, though floatand doublecan hold the prescribed minimum and maximum values but the precision with which each type can represent data may not match what it is you're trying to store. In particular, it's difficult to store exceptionally large numbers with extremely small fractions attached. So float.hprovides a number of other constants that help you to determine if a floator a doublecan,in fact,represent a particular number.
不过,您应该floats.h仔细阅读文章,float并且double可以保存规定的最小值和最大值,但是每种类型可以表示数据的精度可能与您要存储的数据不匹配。特别是,很难存储非常大的带有极小分数的数字。Sofloat.h提供了许多其他常量,可帮助您确定 afloat或 a doublecan 实际上是否代表特定数字。
回答by Glyph
"But glyph", I hear you asking, "what if I have to determine the maximum value for an opaque type whose maximum might eventually change?" You might continue: "What if it's a typedef in a library I don't control?"
“但是字形”,我听到你问,“如果我必须确定一个不透明类型的最大值,它的最大值最终可能会改变呢?” 您可能会继续:“如果它是我无法控制的库中的 typedef 怎么办?”
I'm glad you asked, because I just spent a couple of hours cooking up a solution (which I then had to throw away, because it didn't solve my actual problem).
我很高兴你问,因为我只是花了几个小时来制定一个解决方案(然后我不得不扔掉它,因为它没有解决我的实际问题)。
You can use this handy maxofmacro to determine the size of any valid integer type.
您可以使用这个方便的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)))
You can use it like so:
你可以像这样使用它:
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;
}
If you'd like, you can toss a '(t)' onto the front of those macros so they give you a result of the type that you're asking about, and you don't have to do casting to avoid warnings.
如果您愿意,您可以在这些宏的前面添加一个 '(t)',这样它们就会为您提供您所询问的类型的结果,并且您不必进行强制转换以避免警告。
回答by Explorer09
Maximumvalue of any unsignedintegral type:
任何无符号整数类型的最大值:
((t)~(t)0)// Generic expression that would work in almost all circumstances.(~(t)0)// If you know your typethave equal or larger size thanunsigned int. (This cast forces type promotion.)((t)~0U)// If you know your typethave smaller size thanunsigned int. (This cast demotes type after theunsigned int-type expression~0Uis evaluated.)
((t)~(t)0)// 几乎适用于所有情况的通用表达式。(~(t)0)// 如果您知道您的类型的t大小等于或大于unsigned int. (此施法力型晋升。)((t)~0U)// 如果你知道你的类型t比unsigned int. (在计算unsigned int-type 表达式后,此强制转换将类型降级~0U。)
Maximumvalue of any signedintegral type:
任何有符号整数类型的最大值:
If you have an unsigned variant of type
t,((t)(((unsigned t)~(unsigned t)0)>>1))would give you the fastest result you need.Otherwise, use this (thanks to @vinc17 for suggestion):
(((1ULL<<(sizeof(t)*CHAR_BIT-2))-1)*2+1)
如果您有 type 的无符号变体
t,((t)(((unsigned t)~(unsigned t)0)>>1))则会为您提供所需的最快结果。否则,使用这个(感谢@vinc17 的建议):
(((1ULL<<(sizeof(t)*CHAR_BIT-2))-1)*2+1)
Minimumvalue of any signedintegral type:
任何有符号整数类型的最小值:
You have to know the signed number representation of your machine. Most machines use 2's complement, and so -(((1ULL<<(sizeof(t)*CHAR_BIT-2))-1)*2+1)-1will work for you.
您必须知道机器的签名数字表示。大多数机器使用 2 的补码,因此-(((1ULL<<(sizeof(t)*CHAR_BIT-2))-1)*2+1)-1对您有用。
To detect whether your machine uses 2's complement, detect whether (~(t)0U)and (t)(-1)represent the same thing.
要检测您的机器是否使用 2 的补码,请检测(~(t)0U)和是否(t)(-1)代表相同的事物。
So, combined with above:
所以,结合上面:
(-(((1ULL<<(sizeof(t)*CHAR_BIT-2))-1)*2+1)-(((~(t)0U)==(t)(-1)))
will give you the minimum value of any signed integral type.
将为您提供任何有符号整数类型的最小值。
As an example: Maximum value of size_t(a.k.a. the SIZE_MAXmacro) can be defined as (~(size_t)0). Linux kernel source codedefine SIZE_MAXmacro this way.
例如:(size_t又名SIZE_MAX宏)的最大值可以定义为(~(size_t)0)。Linux 内核源代码以SIZE_MAX这种方式定义宏。
One caveatthough: All of these expressions use either type casting or sizeofoperator and so none of these would work in preprocessor conditionals (#if... #elif... #endifand like).
一个警告,虽然:这些表达式的所有兼用型铸造或sizeof运营商等等这些都不将于预处理条件工作(#if... #elif...#endif和等)。
(Answer updated for incorpoating suggestions from @chux and @vinc17. Thank you both.)
(已更新答案以纳入来自 @chux 和 @vinc17 的建议。谢谢你们。)
回答by rahul gupta
#include<stdio.h>
int main(void)
{
printf("Minimum Signed Char %d\n",-(char)((unsigned char) ~0 >> 1) - 1);
printf("Maximum Signed Char %d\n",(char) ((unsigned char) ~0 >> 1));
printf("Minimum Signed Short %d\n",-(short)((unsigned short)~0 >>1) -1);
printf("Maximum Signed Short %d\n",(short)((unsigned short)~0 >> 1));
printf("Minimum Signed Int %d\n",-(int)((unsigned int)~0 >> 1) -1);
printf("Maximum Signed Int %d\n",(int)((unsigned int)~0 >> 1));
printf("Minimum Signed Long %ld\n",-(long)((unsigned long)~0 >>1) -1);
printf("Maximum signed Long %ld\n",(long)((unsigned long)~0 >> 1));
/* Unsigned Maximum Values */
printf("Maximum Unsigned Char %d\n",(unsigned char)~0);
printf("Maximum Unsigned Short %d\n",(unsigned short)~0);
printf("Maximum Unsigned Int %u\n",(unsigned int)~0);
printf("Maximum Unsigned Long %lu\n",(unsigned long)~0);
return 0;
}
回答by craig65535
I wrote some macros that return the min and max of any type, regardless of signedness:
我写了一些宏来返回任何类型的最小值和最大值,而不管符号:
#define MAX_OF(type) \
(((type)(~0LLU) > (type)((1LLU<<((sizeof(type)<<3)-1))-1LLU)) ? (long long unsigned int)(type)(~0LLU) : (long long unsigned int)(type)((1LLU<<((sizeof(type)<<3)-1))-1LLU))
#define MIN_OF(type) \
(((type)(1LLU<<((sizeof(type)<<3)-1)) < (type)1) ? (long long int)((~0LLU)-((1LLU<<((sizeof(type)<<3)-1))-1LLU)) : 0LL)
Example code:
示例代码:
#include <stdio.h>
#include <sys/types.h>
#include <inttypes.h>
#define MAX_OF(type) \
(((type)(~0LLU) > (type)((1LLU<<((sizeof(type)<<3)-1))-1LLU)) ? (long long unsigned int)(type)(~0LLU) : (long long unsigned int)(type)((1LLU<<((sizeof(type)<<3)-1))-1LLU))
#define MIN_OF(type) \
(((type)(1LLU<<((sizeof(type)<<3)-1)) < (type)1) ? (long long int)((~0LLU)-((1LLU<<((sizeof(type)<<3)-1))-1LLU)) : 0LL)
int main(void)
{
printf("uint32_t = %lld..%llu\n", MIN_OF(uint32_t), MAX_OF(uint32_t));
printf("int32_t = %lld..%llu\n", MIN_OF(int32_t), MAX_OF(int32_t));
printf("uint64_t = %lld..%llu\n", MIN_OF(uint64_t), MAX_OF(uint64_t));
printf("int64_t = %lld..%llu\n", MIN_OF(int64_t), MAX_OF(int64_t));
printf("size_t = %lld..%llu\n", MIN_OF(size_t), MAX_OF(size_t));
printf("ssize_t = %lld..%llu\n", MIN_OF(ssize_t), MAX_OF(ssize_t));
printf("pid_t = %lld..%llu\n", MIN_OF(pid_t), MAX_OF(pid_t));
printf("time_t = %lld..%llu\n", MIN_OF(time_t), MAX_OF(time_t));
printf("intptr_t = %lld..%llu\n", MIN_OF(intptr_t), MAX_OF(intptr_t));
printf("unsigned char = %lld..%llu\n", MIN_OF(unsigned char), MAX_OF(unsigned char));
printf("char = %lld..%llu\n", MIN_OF(char), MAX_OF(char));
printf("uint8_t = %lld..%llu\n", MIN_OF(uint8_t), MAX_OF(uint8_t));
printf("int8_t = %lld..%llu\n", MIN_OF(int8_t), MAX_OF(int8_t));
printf("uint16_t = %lld..%llu\n", MIN_OF(uint16_t), MAX_OF(uint16_t));
printf("int16_t = %lld..%llu\n", MIN_OF(int16_t), MAX_OF(int16_t));
printf("int = %lld..%llu\n", MIN_OF(int), MAX_OF(int));
printf("long int = %lld..%llu\n", MIN_OF(long int), MAX_OF(long int));
printf("long long int = %lld..%llu\n", MIN_OF(long long int), MAX_OF(long long int));
printf("off_t = %lld..%llu\n", MIN_OF(off_t), MAX_OF(off_t));
return 0;
}
回答by Prasoon Saurav
回答by Nixuz
回答by vinc17
To get the maximum value of an unsigned integer type twhose width is at least the one of unsigned int(otherwise one gets problems with integer promotions): ~(t) 0. If one wants to also support shorter types, one can add another cast: (t) ~(t) 0.
为了得到一个无符号整数类型的最大值t,其宽度至少是该一个unsigned int(否则一个得到问题整数促销): ~(t) 0。如果还想支持更短的类型,可以添加另一个类型转换:(t) ~(t) 0.
If the integer type tis signed, assuming that there are no padding bits, one can use:
如果整数类型t是有符号的,假设没有填充位,可以使用:
((((t) 1 << (sizeof(t) * CHAR_BIT - 2)) - 1) * 2 + 1)
The advantage of this formula is that it is not based on some unsigned version of t(or a larger type), which may be unknown or unavailable (even uintmax_tmay not be sufficient with non-standard extensions). Example with 6 bits (not possible in practice, just for readability):
这个公式的优点是它不是基于一些未签名的版本t(或更大的类型),这可能是未知的或不可用的(甚至uintmax_t可能不足以使用非标准扩展)。6 位示例(实际上不可能,只是为了可读性):
010000 (t) 1 << (sizeof(t) * CHAR_BIT - 2)
001111 - 1
011110 * 2
011111 + 1
In two's complement, the minimum value is the opposite of the maximum value, minus 1 (in the other integer representations allowed by the ISO C standard, this is just the opposite of the maximum value).
在二进制补码中,最小值与最大值相反,即负 1(在 ISO C 标准允许的其他整数表示中,这正好与最大值相反)。
Note: To detect signedness in order to decide which version to use: (t) -1 < 0will work with any integer representation, giving 1 (true) for signed integer types and 0 (false) for unsigned integer types. Thus one can use:
注意:要检测符号以决定使用哪个版本:(t) -1 < 0将适用于任何整数表示,为有符号整数类型提供 1(真),为无符号整数类型提供 0(假)。因此可以使用:
(t) -1 < 0 ? ((((t) 1 << (sizeof(t) * CHAR_BIT - 2)) - 1) * 2 + 1) : (t) ~(t) 0
回答by Arjun
MIN and MAX values of any integer data type can be computed without using any library functions as below and same logic can be applied to other integer types short, int and long.
可以在不使用任何库函数的情况下计算任何整数数据类型的 MIN 和 MAX 值,并且相同的逻辑可以应用于其他整数类型 short、int 和 long。
printf("Signed Char : MIN -> %d & Max -> %d\n", ~(char)((unsigned char)~0>>1), (char)((unsigned char)~0 >> 1));
printf("Unsigned Char : MIN -> %u & Max -> %u\n", (unsigned char)0, (unsigned char)(~0));

