In ILP32, char, short, int, long, long long, pointer respectively accounted for 1, 2, 4, 4, 8, 4 bytes,
In LP64, char, short, int, long, long long, pointer respectively accounted for 1, 2, 4, 8, 8, 8 bytes,
Whether in ILP32 or LP64, long long always takes up 8 bytes, the following gives a simple C code implementation to characterize the range of integers.
o FOO.C
1#include <stdio.h>2 /**3 * The size (n bytes) of the basic types4 * =================================5 * Char Short int long long long pointer6 * ----- ---- ----- --- ---- --------- -------7 * LP64 1 2 4 8 8 88 * ILP32 1 2 4 4 8 49 */TentypedefChar__s8; Onetypedef Short__s16; Atypedefint__s32; -typedefLong Long__s64; -typedef unsignedChar__u8; thetypedef unsigned Short__u16; -typedef unsignedint__u32; -typedef unsignedLong Long__u64; - + #defineSMAX8 ((__S8) (((__U8) ~0) >> 1)) - #defineSMAX16 ((__S16) (((__U16) ~0) >> 1)) + #defineSMAX32 ((__S32) (((__u32) ~0) >> 1)) A #defineSMAX64 ((__S64) (((__u64) ~0) >> 1)) at - #definesmin8-smax8 - #definesmin16-smax16 - #definesmin32-smax32 - #defineSmin64-smax64 - in #defineUMAX8 ((__u8) ~0) - #defineUMAX16 ((__u16) ~0) to #defineUMAX32 ((__u32) ~0) + #defineUMAX64 ((__u64) ~0) - the #defineUMIN8 ((__u8) 0) * #defineUMIN16 ((__u16) 0) $ #defineUMIN32 ((__u32) 0)Panax Notoginseng #defineUMIN64 ((__u64) 0) - the intMainintargcChar*argv[]) + { A__s8 smax8 =SMAX8; the__S16 smax16 =SMAX16; +__s32 smax32 =SMAX32; -__s64 smax64 =SMAX64; $__s8 Smin8 =SMIN8; $__S16 Smin16 =SMIN16; -__s32 Smin32 =SMIN32; -__s64 Smin64 =SMIN64; theprintf"s64: [%llx,%llx]\t[%lld,%lld]\n", Smin64, smax64, Smin64, smax64); -printf"S32: [%x,%x]\t\t\t[%d,%d]\n", Smin32, smax32, Smin32, smax32);Wuyiprintf"s16: [%x,%x]\t\t\t\t[%d,%d]\n", Smin16, smax16, Smin16, smax16); theprintf"S8: [%x,%x]\t\t\t\t[%d,%d]\n", Smin8, smax8, Smin8, smax8); -printf"\ n"); Wu -__u8 umax8 =UMAX8; About__u16 umax16 =UMAX16; $__u32 umax32 =UMAX32; -__u64 umax64 =UMAX64; -__u8 Umin8 =UMIN8; -__u16 Umin16 =UMIN16; A__u32 Umin32 =UMIN32; +__u64 Umin64 =UMIN64; theprintf"u64: [%llx,%llx]\t\t\t[%lld,%llu]\n", Umin64, umax64, Umin64, umax64); -printf"u32: [%x,%x]\t\t\t\t[%d,%u]\n", Umin32, umax32, Umin32, umax32); $printf"U16: [%x,%x]\t\t\t\t\t[%d,%u]\n", Umin16, umax16, Umin16, umax16); theprintf"U8: [%x,%x]\t\t\t\t\t[%d,%u]\n", Umin8, umax8, Umin8, umax8); the the return 0; the}
o Compile and Execute
$GCC-g-wall-m32-o foo foo.c$./FOOS64: [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]
Note: integers are represented in memory and complement is used. Because the compilation option I'm using is-m32, then:
1. Non-negative complement equals the source code;
The integer value range of C language