`
superwulei
  • 浏览: 108582 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用C语言浮点数的精度极限比较精确的求近似值

阅读更多

今天继续学习《C语言的科学和艺术》一书,今晚终于结束了第六章算法部分的课后习题,同时我也非常高兴自己已经完成了本书第一部分的学习,很有一种收获的感觉。

今天做的题中有一个知识点,是关于浮点数精度问题的。要知道,在C语言中浮点数类型如同float,double等都是不精确的,万万不可以使用他们做科学计算,否则结果很可能与答案有很大的偏差。算法这一章中介绍了一个浮点数不精确的例子就是如果for循环中的变量是double类型的,如for(double i = 1.0; i <= 2.0; i += 0.1 )。看上去i的值会从1.0,1.1,1.2...一直取到2.0,但是在大多数电脑上是无法取值到2.0的。因为计算机中i最终的值很有可能是1.9999999...我在自己的虚拟机上验证了一下作者所举的例子,证明其正确。

今天我想说的很我第二段中所讲的有些联系,是利用浮点数的精度限制做计算(当然不可能是精确的计算了)。我举个例子吧,比如使用计算机模拟圆周率PI的计算,我们通过一个公式计算,一直计算下去,直到计算机的浮点精度达到极限。这样计算虽然不能够精确的计算出我们想要的答案,但是这个值是计算机所能计算的最近似这个精确值的值。下面我就通过一道练习题说明,这是《C语言的科学和艺术》第六章中最后一道习题。

其实这道题算法非常容易想出,因为规律非常明显。第一项为1,后面的项中分子为1分母为第n-1项的阶乘。
于是,小使了一下逐步求精的设计原则,在主函数中编写了for循环来进行项的相加,并且在其中调用Factorial函数(自定义的求阶乘函数)。请先不要看代码 for循环里面不就是一个sum += 1 / Factorial(n)么?结束了main函数的编写后,开始声明、定义求阶乘的函数Factorial。开始的时候,我将Factorial定义为long类型,参数也定义为long类型,但是最后程序居然报错说浮点数被0所除。我很是不解,最后我将程序改动,将原来的long类型全部修改为double型。现在想想当时的问题,难道是long转换为double型的时候会损失精度?(我曾经测试1.0/Factorial(2),结果居然为0)(Floating point error: Divided by 0) 精度的问题很是令人烦恼。今天的重点不在这个,虽然你可能觉得我连这个都没有搞清楚而不应该往下讲下去,但是下面的内容我是清楚的。我所讲的就是关于如何将计算结果达到浮点数的精度限制的问题,请看代码18行,for循环的循环条件为sum != sum + term。这两个变量都是double性浮点变量,其中term的值是一个越来越小的变量(term永远大于0,因为term = 1 / f, f又大于0 )因此,必然会有一个时刻term将等于0,那是sum = sum + term,循环停止。

收获:学会使用浮点数的精度限制来“比较精确”的计算近似值,使用这一方法在许多计算中非常重要。

代码如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->  1  /*
 2      The Art and Sience of C.
 3     Issue 6, project 10.
 4     Title: e
 5  */
 6  
 7  #include < stdio.h >
 8  #include < math.h >
 9  #include " simpio.h "
10  double  Factorial(  double  n );
11  
12  void  main()
13  {
14       double  e  =   1.0 ;
15       double  term;
16      int  i;
17  
18       for  ( i  =   1 ; e  !=  e  +  term; i ++  )
19      {
20           double  f  =  ( double )Factorial( i );
21          term  =   1.0   /  f;
22          e  +=  term;
23     }
24  
25      printf( " %.10lf\n " ,e);
26  
27      getch();
28      printf( " \n " );
29  }
30  
31  double  Factorial(  double  n )
32  {
33       if ( n  <=   0.0  )
34     {
35        printf( " Illegal parameter!\n " );
36         return   - 1 ;
37     }
38       if ( n  ==   1.0  )    return 1  );
39       if ( n  >   1.0  )     return ( n  *  Factorial( n  -   1  ) );
40  }

分享到:
评论

相关推荐

    c语言浮点数高精度加法计算

    c语言浮点数高精度加法计算

    C语言浮点数运算解惑

    定点数使用整数来表示小数,没有浮点数的表示范围和精度的问题,但是定点数的表示范围有限,尤其对于大数运算或要求高精度的场景,浮点数是更好的选择。 在编程实践中,处理浮点数时要注意精度问题,有时需要根据...

    C语言浮点数转字符串_C语言浮点数字符串_浮点数转换_

    在C语言中,将浮点数转换为字符串是一项常见的任务,尤其在需要将数值数据输出到文件或屏幕上时。这个过程通常涉及到`printf`函数家族的使用,它们能够按照指定的格式将各种类型的数据转化为可读的字符串。本文将...

    C语言浮点数运算

    总之,理解浮点数的存储机制及其带来的精度问题是正确使用C语言中浮点数的关键。在实际编程过程中,应当根据具体的应用场景选择合适的数据类型,并采取适当的措施来规避浮点运算中可能出现的问题。

    C语言中浮点数精度问题分析.pdf

    在C语言编程中,浮点数精度问题是一个常见的问题,它涉及到计算机科学基础中的数值表示方法。由于计算机采用二进制系统存储数据,这使得计算机在处理十进制小数时会出现精度误差。理解这些误差产生的原因是极为重要...

    C语言单精度浮点转换工具

    使用"C语言单精度浮点转换工具",开发者可以输入16进制数值,工具会自动执行以上步骤并显示对应的浮点数结果,大大提高了开发效率。同时,由于该工具是基于C语言开发的,用户还可以查看源代码,学习浮点数转换的具体...

    C语言浮点数转换四字节16进制数工具

    - 在C语言中,可以使用`union`来访问浮点数的字节,或者使用`memcpy`函数将浮点数的内存表示复制到字节数组中。 - 对每个字节进行二进制到16进制的转换,可以自定义函数实现,也可以利用C库函数如`sprintf`,将二...

    嵌入式C语言浮点数到字符数组转换.pdf

    综上所述,本文档提出的浮点数到字符数组的转换方法,是针对嵌入式C语言环境开发的。该方法有效地解决了调用标准库函数导致程序空间增加的问题,同时提供了在嵌入式系统中进行浮点数到字符数组转换的具体实现,具有...

    单精度浮点数与十六进制转换_C语言程序

    在探讨“单精度浮点数与十六进制转换_C语言程序”这一主题时,我们首先需要理解几个核心概念:单精度浮点数、十六进制以及它们之间的转换机制。此外,我们将深入分析C语言中实现这些转换的具体方法,以及如何在...

    克服C语言浮点数的汇编语言处理数据(原创)

    本文将深入探讨如何利用汇编语言来克服C语言在处理浮点数时可能遇到的精度问题,通过具体的程序代码示例,阐述其原理及应用。 ### 汇编语言处理浮点数的优势 在C语言中,浮点数的处理通常依赖于处理器的浮点运算...

    C语言浮点数的二进制表示

    ### C语言浮点数的二进制表示 #### 前言 在计算机科学领域,尤其是在编程语言如C语言中,了解数据类型的底层实现是非常重要的。对于浮点数而言,其内部表示方式决定了如何准确地处理数值计算。本文将深入探讨C语言...

    关于C语言浮点数的存储

    在C语言中,直接使用`==`操作符比较浮点数可能会导致错误的结果,因为微小的计算误差可能导致两个实际上相等的浮点数被视为不相等。为了解决这个问题,通常会设定一个较小的阈值,如`FLT_EPSILON`或`DBL_EPSILON`,...

    浮点数精度问题解答——浮点数

    比较运算和求余操作则要求绝对精确,因为它们涉及到值的精确性质,而不是近似值。例如,两个浮点数的比较应该给出确切的相等或不等结果,而不会受浮点误差的影响。求余运算也必须返回一个精确的浮点结果,考虑到...

    浮点数与十六进制转换

    在处理浮点数精度问题、比较浮点数或实现自定义数学函数时,转换到十六进制可以提供宝贵的洞察力。同时,这种转换在处理硬件交互、网络协议解析以及内存操作等场景也十分常见。 总的来说,理解和掌握浮点数与十六...

    C语言浮点数探析.pdf

    C语言支持多种浮点数类型,主要包括float(单精度)、double(双精度)和long double(长双精度)。本知识点将从这些方面进行详细阐述。 首先,浮点数的存储格式使用两部分表示:尾数(M)和阶码(E)。尾数是二...

    解决javascript中的浮点数计算不精确问题

    5. **使用BigDecimal类**:在某些高级应用中,可以考虑使用类似Java的`BigDecimal`类,它提供了高精度的浮点数运算,但JavaScript原生并不支持,可能需要引入第三方库。 理解JavaScript浮点数计算的局限性并采用...

    java 精确的浮点数运算java 精确的浮点数运算java 精确的浮点数运算

    java 精确的浮点数运算java 精确的浮点数运算java 精确的浮点数运算 java 精确的浮点数运算java 精确的浮点数运算java 精确的浮点数运算 java 精确的浮点数运算java 精确的浮点数运算java 精确的浮点数运算 java ...

    C语言浮点数探析

    因此,在比较浮点数时,通常会使用一个很小的阈值(称为容差)来进行近似比较。 ##### 3. 舍入误差 浮点数运算中不可避免会出现舍入误差,这是由于浮点数表示上的限制造成的。例如,0.1在二进制中是一个无限循环...

    C程序中用union实现浮点数与IEEE格式转换

    USS规定了一套严格的通信规则,关于浮点数参数值,USS规定采用IEEE-754格式进行传送。例如,浮点数50.0,在通信中传送的是它的IEEE-754格式,即4字节的十六进制424800H.因此,单片机的C程序,在发送或接收外围设各的...

    C语言中的浮点数精度问题如何处理?

    在C语言中,浮点数的精度问题是一个常见的挑战,因为它涉及到如何在有限的位数内表示无限的实数。浮点数的存储基于IEEE 754标准,这导致了一些数字无法被精确表示,从而引发了精度问题。以下是处理浮点数精度问题的...

Global site tag (gtag.js) - Google Analytics