C++中的数值类型
变量类型 | 占用字节 | 最大取值 | 最小取值 |
---|---|---|---|
long long | 8 | LLONG_MAX = 2 63 − 1 \text{LLONG\_MAX} = 2^{63}-1 LLONG_MAX=263−1 | LLONG_MIN = − 2 63 \text{LLONG\_MIN} = -2^{63} LLONG_MIN=−263 |
long / int | 4 | INT_MAX = 2 31 − 1 \text{INT\_MAX} = 2^{31}-1 INT_MAX=231−1 | INT_MIN = − 2 31 \text{INT\_MIN} = -2^{31} INT_MIN=−231 |
short | 2 | SHRT_MAX = 2 15 − 1 \text{SHRT\_MAX} = 2^{15}-1 SHRT_MAX=215−1 | SHRT_MIN = − 2 15 \text{SHRT\_MIN} = -2^{15} SHRT_MIN=−215 |
char | 1 | CHAR_MAX = 2 7 − 1 \text{CHAR\_MAX} = 2^{7}-1 CHAR_MAX=27−1 | CHAR_MIN = − 2 7 \text{CHAR\_MIN} = -2^{7} CHAR_MIN=−27 |
double | 8 | DBL_MAX = 1.79769 e + 308 \text{DBL\_MAX} = 1.79769e+308 DBL_MAX=1.79769e+308 | − DBL_MAX = − 1.79769 e + 308 -\text{DBL\_MAX} = -1.79769e+308 −DBL_MAX=−1.79769e+308 |
float | 4 | FLT_MAX = 3.40282 e + 038 \text{FLT\_MAX} = 3.40282e+038 FLT_MAX=3.40282e+038 | − FLT_MAX = − 3.40282 e + 038 -\text{FLT\_MAX} = -3.40282e+038 −FLT_MAX=−3.40282e+038 |
#include <iostream>
using namespace std;
int main() {
long long type_long_long;
cout << typeid(type_long_long).name() << "\t" << sizeof(type_long_long) << "\t"
<< LLONG_MAX << "\t" << LLONG_MIN << "\n\t\t" << -LLONG_MAX << "\t" << -LLONG_MIN << "\n\n";
//__int64 8 9223372036854775807 -9223372036854775808
// -9223372036854775807 -9223372036854775808
long type_long;
cout << typeid(type_long).name() << "\t" << sizeof(type_long) << "\t"
<< LONG_MAX << "\t" << LONG_MIN << "\n\t\t" << -LONG_MAX << "\t" << -LONG_MIN << "\n\n";
//long 4 2147483647 -2147483648
// -2147483647 -2147483648
int type_int;
cout << typeid(type_int).name() << "\t" << sizeof(type_int) << "\t"
<< INT_MAX << "\t" << INT_MIN << "\n\t\t" << -INT_MAX << "\t" << -INT_MIN << "\n\n";
//int 4 2147483647 -2147483648
// -2147483647 -2147483648
short type_short;
cout << typeid(type_short).name() << "\t" << sizeof(type_short) << "\t"
<< SHRT_MAX << "\t" << SHRT_MIN << "\n\t\t" << -SHRT_MAX << "\t" << -SHRT_MIN << "\n\n";
//short 2 32767 -32768
// -32767 32768
char type_char;
cout << typeid(type_char).name() << "\t" << sizeof(type_char) << "\t"
<< CHAR_MAX << "\t" << CHAR_MIN << "\n\t\t" << -CHAR_MAX << "\t" << -CHAR_MIN << "\n\n";
//char 1 127 -128
// -127 128
double type_double;
cout << typeid(type_double).name() << "\t" << sizeof(type_double) << "\t"
<< DBL_MAX << "\t" << DBL_MIN << "\n\t\t" << -DBL_MAX << "\t" << -DBL_MIN << "\n\n";
//double 8 1.79769e+308 2.22507e-308
// -1.79769e+308 -2.22507e-308
float type_float;
cout << typeid(type_float).name() << "\t" << sizeof(type_float) << "\t"
<< FLT_MAX << "\t" << FLT_MIN << "\n\t\t" << -FLT_MAX << "\t" << -FLT_MIN << "\n\n";
//float 4 3.40282e+038 1.17549e-038
// -3.40282e+038 -1.17549e-038
system("pause");
return 0;
}
以上结果可能会催生如下疑问:为什么 int \text{int} int类型的取值范围是 [ − 2 31 , 2 31 − 1 ] [-2^{31},2^{31}-1] [−231,231−1]?为什么 INT_MIN = − INT_MIN \text{INT\_MIN}=-\text{INT\_MIN} INT_MIN=−INT_MIN?这些都是由变量的二进制表示方法决定的。
整形变量的二进制表示
数值在计算机中以二进制形式存储,二进制的存储位数决定了变量的取值范围。若变量大小为1字节,则它的存储位数为8位,数值 13 = 2 3 + 2 2 + 2 0 13=2^3+2^2+2^0 13=23+22+20在该变量中的存储形式为 0000 1101 0000\ 1101 0000 1101。易知1字节变量所能存储的最大值为 1111 1111 1111\ 1111 1111 1111(即十进制的数值 2 8 − 1 = 255 2^8-1=255 28−1=255),最小值为 0000 0000 0000\ 0000 0000 0000,取值范围为 [ 0 , 255 ] [0,255] [0,255]。以此类推,可得4字节的无符号整型 unsigned int \text{unsigned int} unsigned int,变量取值范围为 [ 0 , 2 32 − 1 ] [0,2^{32}-1] [0,232−1]。但是如何表示负数呢?
原码、反码、补码
计算机中的有符号数有三种表示方法,即原码、反码和补码。三种表示方式都将二进制编码的最高位定义为符号位,该位为0时表示正数、为1时表示负数。对于正整数和零,直接取其二进制作为编码;对于负数来说,先取其绝对值的编码,再对该编码取相反数。要从编码中还原数值,先判断符号位,为1则对编码取相反数,再进行进制转换得到绝对值,并根据符号位添加正负号。不同表示方法都遵循该流程,区别在于“取相反数”的操作不同。