2010-01-13 89 views

回答

78

你要使用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 

其中省略出於顯而易見的原因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 

你應該閱讀floats.h文章仔細,雖然floatdouble可以保持規定的最低和最高值,但精度與每種類型的可表示數據可能與您嘗試存儲的內容不匹配。特別是,難以存儲極小數量的極大數字。因此float.h提供了許多其他常量,可幫助您確定floatdouble實際上是否可以表示特定數字。

+1

float的最小值和最大值是多少? – SuperString 2010-01-13 02:10:15

+0

FLT_MAX和FLT_MIN – 2010-01-13 02:35:27

+2

'SIZE_MAX'(size_t'的最大尺寸)是另一個有用的尺寸。 – caf 2010-01-13 03:35:24

3

頭文件limits.h定義了擴展爲標準整數類型的各種限制和參數的宏。

+0

unsigned char的最小值是多少? – SuperString 2010-01-13 01:53:27

+4

@Superstring,任何* unsigned *類型的最小值爲0. – 2010-01-13 01:54:31

+4

我想要負的無符號值! :-) – 2010-01-13 01:58:15

3

查看limits.hfloat.h的這些頁面,這些頁面作爲標準c庫的一部分包含在內。

23

「但字形」,我聽到你問,「如果我必須確定最大值可能最終會改變的不透明類型的最大值?」你可能會繼續說:「如果這是我無法控制的圖書館的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))) 

您可以使用它像這樣:

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

如果你願意,你可以折騰「(T)」到這些宏的前面,所以他們給你的結果輸入你正在詢問的內容,而且你不必進行投射以避免警告。

+0

'〜((t)0)'不能用於最大的無符號? (它不,但我不確定爲什麼)。 – Gauthier 2011-12-05 16:27:42

+0

嗯,它確實有效,但需要你提到的類型轉換。 – Gauthier 2011-12-05 16:34:47

+0

[如何檢測類型是否已簽名](http://stackoverflow.com/a/7470062/991816) – DanSkeel 2015-10-25 12:30:32

3

我寫了一些宏返回任何類型的最小和最大,而不管符號性的:

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

示例代碼:

#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; 
} 
0
任何整數數據類型的

MIN和MAX的值可以是不需要使用任何庫函數就可以計算出來,同樣的邏輯可以應用於其他整型short,int和long。(~(t)0)

符號整型任何的最大值:如果你有一個類型t的無符號的變體,((t)((~(unsigned t)0)>>1))會給你

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)); 
4

任何無符號整型的最大值您需要的最快結果(請參閱下面引用的Linux內核源代碼示例)。否則,你應該使用(~(1ULL<<(sizeof(t)*CHAR_BIT-1)))

最低任何的價值符號整型:你要知道你的機器的符號數表示。大多數機器使用2的補碼,因此-(~(1ULL<<(sizeof(t)*CHAR_BIT-1)))-1將爲您工作。

要檢測您的機器是否使用2的補碼,請檢測(~(t)0U)(t)(-1)是否代表相同的內容。所以,結合以上:

((~(t)0U) == (t)(-1) ? -(~(1ULL<<(sizeof(t)*CHAR_BIT-1)))-1 : 
         -(~(1ULL<<(sizeof(t)*CHAR_BIT-1)))) 

會給你任何有符號整型的最小值。 (其實有這等表示,如果你知道2的補碼錶示例如(t)(1ULL<<(sizeof(t)*CHAR_BIT-1))應相當於(t)(-(~(1ULL<<(sizeof(t)*CHAR_BIT-1)))-1)。)

例如:(〜(爲size_t)0)給你的size_t的最大值。 (你猜怎麼着,這是SIZE_MAX如何在Linux kernel source code #define的。)

一個警告雖然:所有這些表達式的使用型鑄造等不預處理條件(#如果... #elif指令工作... #endif等)。

0

爲了得到一個無符號整數類型t,其寬度至少是unsigned int所述一個(否則一個得到與整數優惠問題)的最大值:~(t) 0

如果整數類型t被簽名,假設沒有填充比特,可使用:

((((t) 1 << (sizeof(t) * CHAR_BIT - 2)) - 1) * 2 + 1) 

此公式的優點是,它不是基於的t一些無符號版本(或一個更大的類型),它可能是未知的或不可用的(即使uintmax_t可能不足以使用非標準擴展)。用6位(在實踐中不可能,只是爲了可讀性)實施例:

010000 (t) 1 << (sizeof(t) * CHAR_BIT - 2) 
001111 - 1 
011110 * 2 
011111 + 1 

在二的補碼,最小值爲最大值的由ISO C允許的對面,減1(在其他整數表示標準,這與最大值恰恰相反)。

3
#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; 
} 
+0

我們可以簡單地得到無符號數據類型的最高值,並從最大值中減去以獲得最小值。 – 2017-11-19 20:18:53

+0

這是一個偉大的,與系統無關的答案,它展示了對類型,內存以及C位運算符的理解。 – 2018-02-07 07:47:00