C++算数过程中的类型转换
一.运算前 - 操作数类型对齐
当两个不同类型的操作数(例如 int 和 double)进行运算时,编译器首先会执行寻常算术转换,将它们提升到共同兼容的类型。
规则:总是提升到精度和范围最大的类型
在算术运算中,编译器遵循以下优先级(简化版):
| 操作数类型 1 | 操作数类型 2 | 共同的运算类型 (结果) | 示例 (A+B) |
|---|---|---|---|
int |
double |
double |
double,然后进行 double 加法。 |
float |
long double |
long double |
long double。 |
short |
int |
int |
int,然后进行 int 加法。 |
int |
unsigned int |
unsigned int |
int 被提升为 unsigned int。(注意:这可能导致意想不到的结果,需谨慎!) |
二.运算后 - 结果类型赋值
一旦计算完成,结果会有一个类型(由阶段一决定),但最终它必须被存储到一个变量中。这个存储变量的类型决定了最终的值。
规则:结果的类型取决于接收变量的类型
这里可能发生两种情况:
A.结果类型 接收变量类型 (安全/提升)
如果运算结果的类型小于或等于接收变量的类型,那么结果会被安全地存储或提升到接收变量的类型。int a = 10;
int b = 3;
// 阶段一: int / int -> 运算结果类型是 int (3)
// 阶段二: 接收变量 double result
double result = a / b;
// 赋值: 结果 (int 3) 被提升并存储为 double 3.0
// result 的值: 3.0
B.结果类型 接收变量类型 (窄化/降级)
如果运算结果的类型大于接收变量的类型,数据可能会丢失(精度丢失或数值溢出)。这被称为窄化转换。
示例 1: 浮点数精度丢失double a = 10.0;
int b = 3;
// 阶段一: double / int -> 运算结果类型是 double (3.333...)
// 阶段二: 接收变量 int result
int result = a / b;
// 赋值: double 结果被强制转换为 int。小数部分 (.333...) 被截断。
// result 的值: 3
示例 2: 显式控制(Casting 的重要性)
为了避免阶段一的整数截断,我们需要在运算前使用 static_cast 强制提升操作数的类型:int a = 10;
int b = 3;
// 阶段一: static_cast<double>(a) / b -> double / int -> 运算结果类型是 double (3.333...)
// 阶段二: 接收变量 double result
double result = static_cast<double>(a) / b;
// result 的值: 3.33333...