今天继续学习《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语言浮点数转字符串
是我博客的pdf形式,本文档来自Unix技术网,方便大家学习使用。
嵌入式C语言浮点数到字符数组转换.pdf
C语言中浮点数精度问题分析.pdf
有些C语言书上说float型的有效位数是6~7位,为什么不是6位或者7位?而是一个变化的6~7位? 浮点数在内存中是如何存放的? float浮点数要比同为4... 如何才能精确比较浮点数真实的大小? 看完本文档,你将会得到答案!
C语言浮点数转换四字节16进制数工具,将浮点数转化为四字节。
C语言单精度浮点转换工具,可将16进制32位数据转换为浮点数,常用于Keil中
C语言浮点数的二进制表示
克服C语言浮点数的汇编语言处理数据,是原创的
单精度浮点数与十六进制转换_C语言程序__单片机也可用
C语言浮点数探析.pdf
浮点数与十六进制转换,c语言开发 Float 转换成16进制(HEX)
USS规定了一套严格的通信规则,关于浮点数参数值,USS规定采用IEEE-754格式进行传送。例如,浮点数50.0,在通信中传送的是它的IEEE-754格式,即4字节的十六进制424800H.因此,单片机的C程序,在发送或接收外围设各的...
主要是介绍浮点数在C语言中的比较存储方式,这个可以探讨一下,与存储整型不同
计算 k *∑(x^i), -m ≤ i ≤ n,精确到小数点后14位(最后要求四舍五入)。 【输入形式】 从文件sigma.in中顺序读入4个由空格分隔的正整数k、x、m、n。(1≤ k、x、m、n ≤ 100)。 【输出形式】 将...
C语言浮点数探析
目前支持二进制浮点数的硬件和软件文档中,几乎都声称其浮点数实现符合IEEE 754标准。那么,什么是IEEE 754标准? 最权威的解释是IEEE754标准本身ANSI/IEEE Std 754-1985《IEEE Standard for Binary Floating-Point...
编写程序利用DFA的原理实现高级语言中浮点数的识别算法
识别浮点数的有穷自动机识别浮点数的有穷自动机识别浮点数的有穷自动机识别浮点数的有穷自动机