Chinaunix首页 | 论坛 | 博客
  • 博客访问: 230218
  • 博文数量: 39
  • 博客积分: 1130
  • 博客等级: 少尉
  • 技术积分: 453
  • 用 户 组: 普通用户
  • 注册时间: 2010-02-26 15:54
文章分类

全部博文(39)

文章存档

2012年(1)

2011年(31)

2010年(7)

分类: C/C++

2011-11-26 13:31:18

 
  1. /*
  2. 题目:
  3. printf("%.20lf\n",1.23456+56789.0007);的输出结果是多少,
  4. 这个结果和笔算的结果一致吗?
  5. 如果希望得到和笔算完全一致的结果,你会怎样设计程序。
  6. */

  7. #include <stdio.h>
  8. #include <stdlib.h>

  9. int main( void )
  10. {
  11.           
  12.   printf("%.20lf\n",1.23456+56789.0007);
  13.   
  14.   system("PAUSE");    
  15.   return 0;
  16. }
     就一般情况而言,很难说
  1. printf("%.20lf\n",1.23456+56789.0007);
的输出结果究竟是什么。因为C语言并没有具体规定double类型的尺寸和表示形式。但在多数计算机上,浮点数采用IEEE 754国际标准。
    在我的机器上
  1. printf("%.20lf\n",1.23456+56789.0007);
的输出结果是:
56790.23525999999400000000
    从这个结果不难发现,尽管输出包含了小数点后面20位 这个结果和笔算结果是不一致的。这个输出结果只是笔算结果的一个近似结果。
    这就是浮点类型数据的一个根本性质——在一般意义上,浮点类型数据只是对有理数的近似表示。代码中的double类型常量1.23456被编译后的二进制表示并不一定就精确等于1.23456而只是1.23456的一个近似值,56789.0007也是如此。这样表达式1.23456+56789.0007求出的同样也是一个近似值就不奇怪了。
    我们平时的笔算和计算机中的浮点运算是不同的。多数情况下平时的笔算是一种精确的计算,它的基础是整数运算,是由几个部分的整数运算的组合。所以如果希望得到和笔算完全一致的结果,应该用整数运算模拟这个过程。
    首先用两个整数分别存储整数部分和小数部分
  1. int zsbf1 = 1 , xsbf1 = 23456 ; //整数部分,小数部分
  2. int zsbf2 = 56789 , xsbf2 = 70 ;
  3. int he_zsbf , he_xsbf ; //存储和
    然后整数部分和小数部分分别相加
  1. he_zsbf = zsbf1 + zsbf2 ;
  2. he_xsbf = xsbf1 + xsbf2 ;
    还要考虑到可能存在的进位
  1. he_zsbf += he_xsbf / 100000 ;
  2. he_zsbf %= 100000 ;
    最后分别输出整数部分和小数部分。
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int main( void )
  4. {
  5.    int zsbf1 = 1 , xsbf1 = 23456 ; //整数部分,小数部分
  6.    int zsbf2 = 56789 , xsbf2 = 70 ;
  7.    int he_zsbf , he_xsbf ; //存储和
  8.    
  9.    he_zsbf = zsbf1 + zsbf2 ;
  10.    he_xsbf = xsbf1 + xsbf2 ;
  11.    he_zsbf += he_xsbf / 100000 ;
  12.    he_xsbf %= 100000 ;
  13.    
  14.    printf("1.23456+56789.0007="
  15.           "%d.%d\n" , he_zsbf , he_xsbf );
  16.           
  17.   system("PAUSE");    
  18.   return 0;
  19. }
运行结果为:
1.23456+56789.0007=56790.23526
请按任意键继续. . .
 
    这个题目的写法并不具备多少一般意义,其中甚至有些非常丑陋的内容,如“10000”这个字面常量以及明显有着人工雕琢过成分的“70”。这个题目的目的在于希望读者理解浮点类型以及浮点运算:浮点类型数据的值并不一定就是在代码中写出的那个浮点常量,浮点运算也并不等同于平时小数运算的那种笔算。浮点类型的本质是:近似地表示以及近似地运算,这一点和整数类型截然不同。
 
阅读(3331) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~