浮点数引起的错误
一、浮点数精度
Float 为单精度,内存中占 4 个字节,有效数位是 7 位。
double为 双精度,占 8 个字节,有效数位是 16 位。
二、常见错误
1. 不能存储全部有效数字
1 2 3 4 5 6 7 8 9 | #include <iostream> int main() { float f{ 0.123456789f }; std::cout << f << '\n' ; return 0; } |
打印:0.123457
2. 采用比较运算符时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <iostream> int main() { double d1{ 100.0 - 99.99 }; // should equal 0.01 mathematically double d2{ 10.0 - 9.99 }; // should equal 0.01 mathematically if (d1 == d2) std::cout << "d1 == d2" << '\n' ; else if (d1 > d2) std::cout << "d1 > d2" << '\n' ; else if (d1 < d2) std::cout << "d1 < d2" << '\n' ; return 0; } |
d1和d2理应一致,但是打印结果为:d1 > d2
如果用Debugger来看,d1 = 0.0100000000000005116 ,d2 = 0.0099999999999997868,这导致了出现了意料之外的结果。
通常来说,用比较运算符是对的,但是当用于比较的两个数非常接近时,可能出现错误。
3. 使用==和!=时
注意!一定不要在比较浮点数时使用==,因为只有当两个数完全一模一样是,才会返回true,否则即使最小的舍入误差都会导致结果为false。
看以下错误出现的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <iostream> int main() { double d{ 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 }; // should sum to 1.0 if (d == 1.0) std::cout << "equal\n" ; else std::cout << "not equal\n" ; return 0; } |
打印结果是:not equal
所以,我们可以用下面这个代码来替代==,
1 2 3 4 5 6 7 8 | #include <cmath> // for std::abs() // epsilon is an absolute value bool approximatelyEqualAbs( double a, double b, double absEpsilon) { // if the distance between a and b is less than absEpsilon, then a and b are "close enough" return std:: abs (a - b) <= absEpsilon; } |
还有一些更严谨的方法,但是实现复杂度也更高,具体查看该网页拓展部分:https://www.learncpp.com/cpp-tutorial/relational-operators-and-floating-point-comparisons/
4. 整数除法
我们对两个整数做除法操作,我们想要的是一个浮点数,但是得到的确会是一个整数。
1 2 3 4 5 6 7 8 9 10 11 | #include <iostream> int main() { int x{ 5 }; int y{ 3 }; std::cout << x << " divided by " << y << " is: " << x / y << '\n' ; // integer division return 0; } |
打印结果为:5 divided by 3 is: 1
我么可以用static_cast函数将其中一个整数转为浮点数,最后得到的结果就是浮点数。或者写成5.0/7.0。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人