Part.I Introduction
首先要说明的一点,不同编译器中相同类型的字节数可能不一样,导致它们们的取值范围不一样。本文主要针对LeetCode
,所以内容仅供参考。
Part.II 各类型取值范围
变量名 | 字节数 | 数据范围 |
---|---|---|
char | 1 | -128 ~ 127 |
short | 2 | -32767 ~ 32768 |
unsigned short | 2 | 0 ~ 65535 |
int | 4 | − 2.1 × 1 0 9 ∼ 2.1 × 1 0 9 -2.1\times 10^{9} \sim 2.1\times 10^{9} −2.1×109∼2.1×109 |
unsigned int | 4 | 0 ∼ 4.3 × 1 0 9 0 \sim 4.3\times 10^{9} 0∼4.3×109 |
long | 8 | − 9 × 1 0 18 ∼ 9 × 1 0 18 -9\times 10^{18} \sim 9\times 10^{18} −9×1018∼9×1018 |
unsigned long | 8 | 0 ∼ 1.8 × 1 0 19 0 \sim 1.8\times 10^{19} 0∼1.8×1019 |
long long | 8 | − 9 × 1 0 18 ∼ 9 × 1 0 18 -9\times 10^{18} \sim 9\times 10^{18} −9×1018∼9×1018 |
float | 4 | ± 3.4 × 1 0 − 38 ∼ ± 3.4 × 1 0 38 ±3.4\times 10^{-38}\sim±3.4\times 10^{38} ±3.4×10−38∼±3.4×1038,1 位符号位,8 位指数位,23 位尾数位;小数点后有效数字 7 位(精度) |
double | 8 | ± 1.7 × 1 0 − 308 ∼ ± 1.7 × 1 0 308 ±1.7\times 10^{-308}\sim±1.7\times 10^{308} ±1.7×10−308∼±1.7×10308,1 位符号位,11 位指数位,52 位小数位;小数点后有效数字 15 位(精度) |
#include <climits>
和 #include <float.h>
头文件其实已经用常量记录了不同变量的数据范围。下面是该头文件中的所有符号常量,我们可以通过这些常量查看不同变量的数据范围。
------------------ #include <climits> -------------------------
CHAR_MIN char 最小值
SCHAR_MAX signed char 最大值
SCHAR_MIN signed char 最小值
UCHAR_MAX unsigned char 最大值
SHRT_MAX short 最大值
SHRT_MIN short 最小值
USHRT_MAX unsigned short 最大值
INT_MAX int 最大值
INT_MIN int 最小值
UINT_MAX unsigned int 最大值
UINT_MIN unsigned int 最小值
LONG_MAX long 最大值
LONG_MIN long 最小值
ULONG_MAX unsigned long 最大值
LLONG_MAX long long 最大值
LLONG_MIN long long 最小值
------------------ #include <float.h> -------------------------
FLT_MANT_DIG float 类型的尾数
FLT_DIG float 类型的最少有效数字位数
FLT_MIN_10_EXP 带有全部有效数的float类型的负指数的最小值(以10为底)
FLT_MAX_10_EXP float 类型的正指数的最大值(以10为底)
FLT_MIN 保留全部精度的 float 类型正数最小值
FLT_MAX float 类型正数最大值
// 还有关于 double 的,就不详细列举了
Part.III 一些技巧
在用 C++ 刷题的时候,很容易因为两个大数相加或相乘导致数据溢出,所以这时候就需要注意了:
- 隐式类型转换:一个大类型与一个小类型做运算,最后得到一个大类型的数据(除非把它赋值给一个小类型)。比如,一个
long
与一个int
做运算,最后得到一个long
,但是如果将结果赋值给一个int
,那么赋值的时候会『截位』。 - 强制类型转换:当两个小类型进行运算的时候,如果运算结果超出了该类型能表示的范围,需用强制类型转换将其转换为大类型。比如,当两个
int
做乘法运算时,可以用long long ans = (long long)a * b;
。后面的a * b
不要括号,也就是说先将一个转换为大类型,然后根据隐式类型转换,得到的结果也是大类型,所以就不会溢出了。要括号的话还是会有问题。