首页 > 代码库 > C语言的整数取值范围

C语言的整数取值范围

在ILP32中, char, short, int, long, long long, pointer分别占1, 2, 4, 4, 8, 4个字节,
在 LP64中, char, short, int, long, long long, pointer分别占1, 2, 4, 8, 8, 8个字节,
无论是在ILP32中还是LP64中, long long总是占8个字节,下面给出简单的C代码实现表征出整数的取值范围。

o foo.c

 1 #include <stdio.h>
 2 /**
 3  * The size (n bytes) of basic types
 4  * =================================
 5  *        char short int long long long pointer
 6  * -----  ---- ----- --- ---- --------- -------
 7  *  LP64     1     2   4    8         8       8
 8  * ILP32     1     2   4    4         8       4
 9  */
10 typedef char                    __s8;
11 typedef short                   __s16;
12 typedef int                     __s32;
13 typedef long long               __s64;
14 typedef unsigned char           __u8;
15 typedef unsigned short          __u16;
16 typedef unsigned int            __u32;
17 typedef unsigned long long      __u64;
18 
19 #define SMAX8   ((__s8 )(((__u8 )~0) >> 1))
20 #define SMAX16  ((__s16)(((__u16)~0) >> 1))
21 #define SMAX32  ((__s32)(((__u32)~0) >> 1))
22 #define SMAX64  ((__s64)(((__u64)~0) >> 1))
23 
24 #define SMIN8   -SMAX8
25 #define SMIN16  -SMAX16
26 #define SMIN32  -SMAX32
27 #define SMIN64  -SMAX64
28 
29 #define UMAX8   ((__u8 )~0)
30 #define UMAX16  ((__u16)~0)
31 #define UMAX32  ((__u32)~0)
32 #define UMAX64  ((__u64)~0)
33 
34 #define UMIN8   ((__u8 )0)
35 #define UMIN16  ((__u16)0)
36 #define UMIN32  ((__u32)0)
37 #define UMIN64  ((__u64)0)
38 
39 int main(int argc, char *argv[])
40 {
41         __s8  smax8  = SMAX8;
42         __s16 smax16 = SMAX16;
43         __s32 smax32 = SMAX32;
44         __s64 smax64 = SMAX64;
45         __s8  smin8  = SMIN8;
46         __s16 smin16 = SMIN16;
47         __s32 smin32 = SMIN32;
48         __s64 smin64 = SMIN64;
49         printf("s64: [%llx, %llx]\t[%lld, %lld]\n", smin64, smax64, smin64, smax64);
50         printf("s32: [%x, %x]\t\t\t[%d, %d]\n",     smin32, smax32, smin32, smax32);
51         printf("s16: [%x, %x]\t\t\t\t[%d, %d]\n",   smin16, smax16, smin16, smax16);
52         printf("s8 : [%x, %x]\t\t\t\t[%d, %d]\n",   smin8,  smax8,  smin8,  smax8);
53         printf("\n");
54 
55         __u8  umax8  = UMAX8;
56         __u16 umax16 = UMAX16;
57         __u32 umax32 = UMAX32;
58         __u64 umax64 = UMAX64;
59         __u8  umin8  = UMIN8;
60         __u16 umin16 = UMIN16;
61         __u32 umin32 = UMIN32;
62         __u64 umin64 = UMIN64;
63         printf("u64: [%llx, %llx]\t\t\t[%lld, %llu]\n", umin64, umax64, umin64, umax64);
64         printf("u32: [%x, %x]\t\t\t\t[%d, %u]\n",       umin32, umax32, umin32, umax32);
65         printf("u16: [%x, %x]\t\t\t\t\t[%d, %u]\n",     umin16, umax16, umin16, umax16);
66         printf("u8 : [%x, %x]\t\t\t\t\t[%d, %u]\n",     umin8,  umax8,  umin8,  umax8);
67 
68         return 0;
69 }

o 编译并执行

$ gcc -g -Wall -m32 -o foo foo.c
$ ./foo
s64: [8000000000000001, 7fffffffffffffff]       [-9223372036854775807, 9223372036854775807]
s32: [80000001, 7fffffff]                       [-2147483647, 2147483647]
s16: [ffff8001, 7fff]                           [-32767, 32767]
s8 : [ffffff81, 7f]                             [-127, 127]

u64: [0, ffffffffffffffff]                      [0, 18446744073709551615]
u32: [0, ffffffff]                              [0, 4294967295]
u16: [0, ffff]                                  [0, 65535]
u8 : [0, ff]                                    [0, 255]

注意: 整数在内存中的表示,一律采用补码。 因为我使用的编译选项是-m32, 那么:

1. 非负数的补码等于源码;

 

C语言的整数取值范围