一、类型转换陷阱
1. 隐式转换
int a = 5; int b = 2; double c = a / b; // ❌ 结果是 2.0,不是 2.5!(整数除法) double d = a / 2.0; // ✅ 结果是 2.5(自动提升为 double) double e = double(a) / b; // ✅ 显式转换,结果 2.5规则:运算时先统一类型,再计算。
2. 混合运算的优先级
int a = 1e9; // 1000000000 long long b = 1e9 * 1e9; // ❌ 溢出!先算 int*int,结果还是 int long long c = 1LL * 1e9 * 1e9; // ✅ 1LL 强制提升为 long long技巧:在表达式开头加1LL、1.0等强制提升类型。
二、浮点数精度问题
1. 不要直接用==比较
double a = 0.1 + 0.2; double b = 0.3; if (a == b) cout << "相等"; // ❌ 可能不相等!(二进制精度误差) // ✅ 正确做法:比较误差范围 const double EPS = 1e-9; if (fabs(a - b) < EPS) cout << "相等";2. 大数吃小数
double big = 1e20; double small = 1.0; double result = big + small - big; // ❌ 结果是 0,small 被"吃掉"了3. 累积误差
// ❌ 累加很多小数会产生误差 double sum = 0; for (int i = 0; i < 10000; i++) sum += 0.0001; // sum 可能不是 1.0 // ✅ Kahan 求和算法(高精度) double sum = 0, c = 0; // c 是补偿值 for (int i = 0; i < 10000; i++) { double y = 0.0001 - c; double t = sum + y; c = (t - sum) - y; sum = t; }三、输入输出技巧
1. 去除浮点数末尾无意义的 0
double x = 2.50000; cout << fixed << setprecision(10) << x << endl; // 2.5000000000(丑) // ✅ 方法:用字符串处理或 boost,或简单判断 cout << setprecision(10); if (x == floor(x)) cout << (long long)x; // 整数部分 else cout << x;2. 快速 IO 与浮点精度冲突
ios::sync_with_stdio(0); cin.tie(0); // 开启后,printf/scanf 和 cin/cout 混用可能出问题 // 浮点输出建议统一用一种3. 科学计数法控制
double x = 123456789.0; cout << scientific << x << endl; // 1.234568e+08 cout << fixed << x << endl; // 123456789.000000 cout << defaultfloat << x << endl; // 123456789(自动选择)四、竞赛/算法中的实用技巧
1. 整数二分 vs 浮点二分
// 整数二分(找边界) while (l < r) { int mid = (l + r) >> 1; if (check(mid)) r = mid; else l = mid + 1; } // 浮点二分(固定次数,避免死循环) for (int i = 0; i < 100; i++) { // 跑 100 次足够精度 double mid = (l + r) / 2; if (check(mid)) r = mid; else l = mid; }2. 输出指定位数(四舍五入)
double x = 3.14159; cout << round(x * 100) / 100; // 保留 2 位小数,输出 3.14 // 或 cout << fixed << setprecision(2) << x; // 3.143. 防止pow的精度爆炸
// ❌ pow 可能不精确 double x = pow(2, 10); // 1024,但可能是 1023.9999999 // ✅ 整数幂用快速幂,或自己乘 long long p = 1; for (int i = 0; i < 10; i++) p *= 2; // 精确的 1024五、结语:
希望本章能够帮助到您~,码字不易,感谢您的点赞收藏o(* ̄▽ ̄*)ブ