注册 登录
编程论坛 C++教室

为什么我老是能遇到这种超级简单又奇葩的问题 求大神搭救!!

okokpypy 发布于 2020-07-13 11:04, 2701 次点击
#include <iostream>
using namespace std;

int main() {
float a, f = 4.4;
while (f > 0) {
cin >> a;
f -= a;
cout << f << endl;
}
return 0;
}
请依次输入1.1、2.2、1.1结果竟然不是0 !? (编译器vc 6.0)
求原因~
6 回复
#2
rjsp2020-07-13 12:00
这个,计算机前几节课就应该告诉你 浮点数 不是 实数 吧!
即使没有,那数学课上也讲过 进制科学表达式,固定位的某个进制的数 转化为另一种进制时,可能是无限循环小数。
浮点数是一种二进制形式的科学表达式。

一种可能(非一定)的情况:
float f = 4.4;
此时 f 的值为 4.400000095367431640625

输入 1.1
a 的值为 1.10000002384185791015625
f -= a; 后 f 的值为 3.30000019073486328125

输入 2.2
a 的值为 2.2000000476837158203125
f -= a; 后 f 的值为 1.1000001430511474609375

输入 1.1
a 的值为 1.10000002384185791015625
f -= a; 后 f 的值为 0.00000011920928955078125
#3
okokpypy2020-07-13 13:49
回复 2楼 rjsp
所以浮点数的运算能否得到正确的值 完全看运气?!
这种运算的不稳定性 会否影响到程序的稳定性?
#4
倾听心跳2020-07-13 14:38
一般对这种运算都采用double,对最后计算的结果会去精确小数位,防止精度溢出的问题
#5
rjsp2020-07-13 14:39
以下是引用okokpypy在2020-7-13 13:49:54的发言:
所以浮点数的运算能否得到正确的值 完全看运气?!
这种运算的不稳定性 会否影响到程序的稳定性?


这取决于你认为什么是“正确的值”。在计算机看来,4.4f - 1.1f - 2.2f - 1.1 的结果无论是 小于0、等于0,还是 大于0,都是正确的。
打个比方,你的身高1米8,但我们都知道任何一个物体长度值接近100%的可能是无理数,那我说你身高180cm错了吗?要求精度达到1cm时,正确;要求精度达到1mm时,错误。

你要追求纯数学上的严格相等,你就不应该使用浮点数。比如你可以用 44 - 11 - 22 - 11,其中每个数的量纲你可以在逻辑上认定它们是 0.1。
#6
lin51616782020-07-13 16:38
浮点数相等有固定格式
fabs(x-y) < 自定义精度
表示 x 等于 y

有兴趣了解为什么要用固定格式 请搜索IEEE 754
没兴趣了解就简单背下来
#7
青山七海2020-07-23 23:06
回复 3楼 okokpypy
哈哈哈,因为计算机和我们用的进制不同啊,内部是二进制,我们是十进制。

具体的不好说,你自己百度一下,反正就是二进制、十进制无法相互精确表示浮点数。

打个比方把:你说中文,老外说英文。然后你用中文和老外讲话,老外A用英文讲给老外B,然后老外B他再用中文讲回给你,整个句子肯定不会一模一样。

所以,你不可能得到精确结果的。

如果你用过数学软件,会发现它们得到的解都很奇怪。比如你用纸笔算出来结果是1,但是计算机告诉你是0.9999999998.这就是浮点数误差的原因了。
1