整数转换先看目标类型范围,再看是否混入无符号或收窄;static_cast 只表达意图,不做边界校验。实用做法是把“检查范围后再转换”封装成统一逻辑。
先弄清楚整数类型范围
先确认源值是否落在目标类型可表示区间,尤其 long 为 4/8 字节,依赖平台。边界可用 std::numeric_limits 查询:
| 类型 | 大小 | 范围 |
|---|---|---|
| char | 1 | -128~127 |
| short | 2 | -32,768~32,767 |
| int | 4 | -2,147,483,648~2,147,483,647 |
| long | 4/8 | 依赖于平台 |
| long long | 8 | -9,223,372,036,854,775,808~9,223,372,036,854,775,807 |
#include <iostream>
#include <limits>
int main() {
std::cout << std::numeric_limits<int>::min()
<< " 到 " << std::numeric_limits<int>::max() << std::endl;
}
C++ 整数转换到底按什么规则发生
| 源类型 | 目标类型 | 规则 |
|---|---|---|
| 较小类型 | 较大类型 | 通常无数据丢失 |
| 有符号类型 | 无符号类型 | 可能改变语义 |
| 较大类型 | 较小类型 | 可能截断 |
unsigned int unsignedInt = -1;
int largeValue = 70000;
short smallValue = static_cast<short>(largeValue); // 可能的截断
怎样把整数转换写成可验证、可复用的安全逻辑
统一封装范围检查,超界就拒绝转换:
#include <iostream>
#include <limits>
#include <stdexcept>
template <typename DestType, typename SourceType>
DestType safeCast(SourceType value) {
if (value > std::numeric_limits<DestType>::max() ||
value < std::numeric_limits<DestType>::min()) {
throw std::overflow_error("转换将导致溢出");
}
return static_cast<DestType>(value);
}
bool isValueInRange(long long value, int bits) {
long long minValue = -(1LL << (bits - 1));
long long maxValue = (1LL << (bits - 1)) - 1;
return value >= minValue && value <= maxValue;
}
- 转换前先验证范围。
- 警惕负数与无符号混用。
- 收窄转换优先走统一
safeCast。
总结:判断一次整数转换是否可靠的最短路径
最短路径就是:先看目标类型范围,再确认是否有符号/无符号混用,最后决定是否需要显式检查或异常处理。
















