C++中double值的处理
近日看见了一张来自网上的图
父亲看见这图就觉得十分有意思,就给许多村里的大学生们看让他们算,如图这是一道并不难的三元一次方程组问题,我心里一盘算觉得正常算并不能体现我IT精英的与众不同,于是我就说看我变个程序来解题。结果当然遵循装B遭雷劈的至高真理。
这道题目的答案是3.5,4.5,9.5和3.5。
为了尽快解决问题我就是用了最简单的逻辑方法让计算机用大量的运算去堆答案代码如下
1 #include<iostream> 2 using namespace std; 3 void main() 4 { 5 double a, b, c; 6 for (a = 0; a <= 10; a += 0.1) 7 { 8 for (b = 0; b <= 10; b += 0.1) 9 { 10 for (c = 0; c <= 10; c += 0.1) 11 { 12 if (a + b == 8 && c - a == 6 && a + c == 13) 13 { 14 cout << a << b << c; 15 } 16 } 17 } 18 } 19 system("pause"); 20 }
按照如图的逻辑似乎没有任何问题然而运行却并不能得到结果我百思不得其解于是就一步一步地调试去看每次循环各变量的值
可以看到上图中所有变量的值都不是我们真正设定的值,他们是无限接近的近似值所以并不存在满足判断条件的a,b,c的值
我也就没能得到答案,而我又不死心的再次去尝试,发现如果我把初始值设为3.4,4.4,9.4,即只循环一次就可以得到正确结果
然后就成功的输出了
这就很尴尬了据我大一新生的揣测,我觉得是因为double类型是以二进制存储数据显然产生无限接近设定值的实际值的原因是遇到了二进制除不尽的值,如3.3所以在第一幅图中因为设定的初始值是3.3 所以从一开始就是一个注定不能得到小数点后一位的值所以运算失败,而第二次我们把初值改为了3.4于是得到了正常的小数,所以经过一次+0.1计算后便得到了符合条件的值。成功得到了答案(注意这里0.1也是默认为double类型的值所以如果你累加的是0.3,那么仍然的不到想要的准确值)。
因为C++只是在学校老师教了一点所以我并没有继续研究如何解决这操蛋的问题,幸好我还自学了C#想到了C#中的十进制类型decimal于是我又用C#写了一遍
1 using System; 2 namespace 计算 3 { 4 class Program 5 { 6 static void Main(string[] args) 7 { 8 decimal a, b, c; 9 for(a=0m; a <= 10m; a+=0.1m) 10 { 11 for (b = 0m; b<= 10m; b+=0.1m) 12 { 13 for (c = 0m; c <= 10m; c+=0.1m) 14 { 15 if (a+b == 8m && c-a == 6m&&a+c==13m) 16 { 17 Console.WriteLine("a={0},b={1},c={2}", a, b,c); 18 } 19 } 20 } 21 } 22 Console.ReadKey(); 23 } 24 } 25 }
妥妥的十进制,爽。
大一刚读完有什么不对的地方多多指教