数值分析_调和级数收敛问题
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
那么, n 244 1.76 1013 。这说明,大数吃小数发生在下溢发生之前,下溢也不 会是和收敛的原因。 至此,已经分析出来 double 型调和级数的收敛原因是大数吃小数,接下来应该精 确计算 n 的收敛值。可用迭代法: (1)n=244 时
sum ln(244 ) 0.57721566490 31.0757 25 1 0.00 01 24 253 24 249 n 52个 0 n 249
n 248 2 109 ,之所以选择从这个数开始累加,是因为它已经和理论分析得到的 248
3
数据与算法实验
xxห้องสมุดไป่ตู้x
20xx/x
很接近了,只留下来两亿个数让计算机累加,时间是可以忍受的。另外虽然初始化 sum=33.8 这个值是用欧拉公式估计的并且导致实验最终得到的 sum 不精确,但是却可 以快速找到收敛的 n 的精确值。下面是实验结果:
31
30
23 22 尾数域
0 ]
[符号域][ 阶数域 ][
收敛时 sum 约为 15,阶数域应该是 00000011,即十进制的+3。1/n 与之相加时, 由于 1/n 很小,要和这个大数阶数域对齐,阶数域应该也是+3。当
1 0.00 01 23 224 23 221 n 23个 0
[符号域][ 阶数域 ][
所以其收敛原因目前还不能判定是大数吃小数,也有可能是上溢或下溢,需要依次判别 哪一种原因下收敛的 n 更小一些。 上溢
如果 sum 在计算过程中上溢,则 sum 应该超出了 double 型浮点数的表示范围
1.7 10308 。用调和级数近似求和公式 S (n) ln n 0.57721056
4
数据与算法实验
xxxx
20xx/x
另外,这种算法的收敛条件也是大数吃小数, 不过因为这个大数只是 sum 的很小一 部分(只有 ln(a)这么大),所以收敛的 n 值可以很大。
3.1.2
实验结果 a=3m 时
虽然 sum 并没有收敛,但是可以看出,当 n=17714700 时,sum=17.1793,与用欧拉 公式预测的值 17.2671 已经有一定差距了。所以需要让 a 小一些。比如下面的例子。 n=1.01m 时
可见收敛的 n=248,收敛的和数约为 33.8483。 为了验证这个结果,在计算机上编程验证。考虑到让计算机从 1 开始计算 1/n 的累 加和是很漫长的过程(这也是为什么在分析 double 型的时候没有像前面分析 float 一样 先通过实验找到确切结果),但是这个收敛过程其实是可以从某一个确定的 n 值来模拟 的。在初始化的时候直接将 sum 初始化为 33.8,并且在累加的时候直接让
323
323
量
) 744 ,它小于 210,阶数域上应该为 00 000 001 001(即
2
数据与算法实验
xxxx
20xx/x
十进制的 9) ,要发生大数吃小数, 1/n 的阶数域也应该是 9, 类似 float 型的分析方法, 有
1 0.00 01 29 253 29 244 n 52个 0
4 5
问题 3:分析上一问的正确性 ..................................................................................... 8 问题 4:积分图误差来源 ............................................................................................. 9 5.1 5.2 背景 ................................................................................................................... 9 分析来源 .......................................................................................................... 10
6
问题与体会 ................................................................................................................. 10
数据与算法实验
xxxx
20xx/x
1 实验内容描述
1.用 float 和 double 类型分别计算序列求和,试判定是否收敛,收敛的条件是 什么,实验给出并从理论上分析收敛时的 n=? 2.设计通用的求和算法, 使得收敛时的 n 尽量大, 所求得的和尽量大 (使用 float 型来计算)。 3. 设计方案,验证所求结果的正确性(使用 float 型计算) 4. 设计方案,验证并解释分析“积分图”快速求解“局部和”误差的来源。 返回目录
经比照,它确实是 248。 综上所述,调和级数和收敛的 n 值分别为: Float 型 Double 型 221 248 返回目录
3 问题 2:通用算法
3.1 Huffman Alike Summation
3.1.1 理论分析
类似 Huffman Tree 的思想,将小数先加起来再加大数,这样有效地避免了小数被大 数吃掉的现象,因为很多个小数加起来之后的总值还是比较大的。 那么,这个算法的关键就是如何进行分块。为了使收敛的 n 尽量大,这个分块方法 应该是动态的,也就是说,n 越大的时候,加的项数应该越多,才能保证每一块加出来 的和都是相近的。如下:
2 问题 1:理论分析 n 的值
2.1 Float
对于 float 的情况,可以先通过实验对累加和与加上 1/i 之后的值是否相等来判敛。 我对每 10 万次的求和结果打印输出,并且在收敛时停止,结果如图(这里多输出了一 些小数点后数字,其实小数点后只有 6-7 位有效数字):
可见,当 n=2097152=221 时收敛。而这个 n 显然不会造成 1/n 的下溢,因为 1/n 远 远大于 float 能表示的最小正数(约1.5 10
问题 2:通用算法 ........................................................................................................ 4 3.1 Huffman Alike Summation .................................................................................. 4 3.1.1 3.1.2 3.2 理论分析 ................................................................................................. 4 实验结果 ................................................................................................. 5
时, 1/n 的尾数域全部是 0,这时我们就将看到 sum 收敛了。 可以看出,这时的 n=221, 实验结果得到了解释。 返回目录
2.2 Double
有了分析 float 型调和级数收敛的基础,我们可以用类似的方法分析 double 型调和 级数。不过有些不同的是,double 型有 64 个 bit,而且存储方式和 float 不相同: 63 62 52 51 尾数域 0 ]
数据与算法实验报告
Electronics Engineering xxxxx 20xx 年 x 月
数据与算法实验
xxxx
20xx/x
目录
1 2 实验内容描述 ............................................................................................................... 1 问题 1:理论分析 n 的值 ............................................................................................. 1 2.1 2.2 3 Float ................................................................................................................... 1 Double ................................................................................................................ 2
For n:1 to INF temp+=1.0f/n; if n>a*m //a是一个大于 1的实数, a越接近1,精度越高。 sum+=temp; cout<<"n="<<n<<" sum="<<sum<<endl; temp=0; m=n; //n作为 m的新值
这种方法,可以在 n 很大的时候保证每一块的和值是差不多大的,因为根据欧拉公 式,S(n)-S(m)=ln(n/m)=ln(a)。
知,这个时候的
n e1.710 ,它大致为1010 量级。
下溢
324
308
308
如果 1/n 下溢, 粗略看 1/n 应该小于 double 数的最小正数 5.0 10 量级。显然下溢发生在上溢出现之前,收敛原因不会是上溢。 大数吃小数
, 则 n 为10
323
只要分析在下溢发生时, 是否已经发生了大数吃小数的情况即可。 当 n 约为10 级时,sum 约为 sum ln(10
38 45
);收敛和 15.403„„也远远小于最大整
数(约 3.4 10 )不会造成部分求和的上溢,所以只可能是发生了大数吃小数的情况。 下面从理论上分析为什么在 n=221 处收敛。因为 float 型浮点数用 32bit 内存来存储 数据,具体 bit 位分布为
1
数据与算法实验
xxxx
20xx/x
Kahan ................................................................................................................. 6 3.2.1 3.2.2 3.2.3 举例分析 ................................................................................................. 6 理论分析 ................................................................................................. 7 实验结果 ................................................................................................. 7
(2)n=249 时
sum ln(249 ) 0.57721566490 34.5414 26 1 0.00 01 25 253 25 248 n 52个 0 n 248
(3)n=248 时
sum ln(248 ) 0.57721566490 33.8483 26 1 0.00 01 25 253 25 248 n 52个 0 n 248
sum ln(244 ) 0.57721566490 31.0757 25 1 0.00 01 24 253 24 249 n 52个 0 n 249
n 248 2 109 ,之所以选择从这个数开始累加,是因为它已经和理论分析得到的 248
3
数据与算法实验
xxห้องสมุดไป่ตู้x
20xx/x
很接近了,只留下来两亿个数让计算机累加,时间是可以忍受的。另外虽然初始化 sum=33.8 这个值是用欧拉公式估计的并且导致实验最终得到的 sum 不精确,但是却可 以快速找到收敛的 n 的精确值。下面是实验结果:
31
30
23 22 尾数域
0 ]
[符号域][ 阶数域 ][
收敛时 sum 约为 15,阶数域应该是 00000011,即十进制的+3。1/n 与之相加时, 由于 1/n 很小,要和这个大数阶数域对齐,阶数域应该也是+3。当
1 0.00 01 23 224 23 221 n 23个 0
[符号域][ 阶数域 ][
所以其收敛原因目前还不能判定是大数吃小数,也有可能是上溢或下溢,需要依次判别 哪一种原因下收敛的 n 更小一些。 上溢
如果 sum 在计算过程中上溢,则 sum 应该超出了 double 型浮点数的表示范围
1.7 10308 。用调和级数近似求和公式 S (n) ln n 0.57721056
4
数据与算法实验
xxxx
20xx/x
另外,这种算法的收敛条件也是大数吃小数, 不过因为这个大数只是 sum 的很小一 部分(只有 ln(a)这么大),所以收敛的 n 值可以很大。
3.1.2
实验结果 a=3m 时
虽然 sum 并没有收敛,但是可以看出,当 n=17714700 时,sum=17.1793,与用欧拉 公式预测的值 17.2671 已经有一定差距了。所以需要让 a 小一些。比如下面的例子。 n=1.01m 时
可见收敛的 n=248,收敛的和数约为 33.8483。 为了验证这个结果,在计算机上编程验证。考虑到让计算机从 1 开始计算 1/n 的累 加和是很漫长的过程(这也是为什么在分析 double 型的时候没有像前面分析 float 一样 先通过实验找到确切结果),但是这个收敛过程其实是可以从某一个确定的 n 值来模拟 的。在初始化的时候直接将 sum 初始化为 33.8,并且在累加的时候直接让
323
323
量
) 744 ,它小于 210,阶数域上应该为 00 000 001 001(即
2
数据与算法实验
xxxx
20xx/x
十进制的 9) ,要发生大数吃小数, 1/n 的阶数域也应该是 9, 类似 float 型的分析方法, 有
1 0.00 01 29 253 29 244 n 52个 0
4 5
问题 3:分析上一问的正确性 ..................................................................................... 8 问题 4:积分图误差来源 ............................................................................................. 9 5.1 5.2 背景 ................................................................................................................... 9 分析来源 .......................................................................................................... 10
6
问题与体会 ................................................................................................................. 10
数据与算法实验
xxxx
20xx/x
1 实验内容描述
1.用 float 和 double 类型分别计算序列求和,试判定是否收敛,收敛的条件是 什么,实验给出并从理论上分析收敛时的 n=? 2.设计通用的求和算法, 使得收敛时的 n 尽量大, 所求得的和尽量大 (使用 float 型来计算)。 3. 设计方案,验证所求结果的正确性(使用 float 型计算) 4. 设计方案,验证并解释分析“积分图”快速求解“局部和”误差的来源。 返回目录
经比照,它确实是 248。 综上所述,调和级数和收敛的 n 值分别为: Float 型 Double 型 221 248 返回目录
3 问题 2:通用算法
3.1 Huffman Alike Summation
3.1.1 理论分析
类似 Huffman Tree 的思想,将小数先加起来再加大数,这样有效地避免了小数被大 数吃掉的现象,因为很多个小数加起来之后的总值还是比较大的。 那么,这个算法的关键就是如何进行分块。为了使收敛的 n 尽量大,这个分块方法 应该是动态的,也就是说,n 越大的时候,加的项数应该越多,才能保证每一块加出来 的和都是相近的。如下:
2 问题 1:理论分析 n 的值
2.1 Float
对于 float 的情况,可以先通过实验对累加和与加上 1/i 之后的值是否相等来判敛。 我对每 10 万次的求和结果打印输出,并且在收敛时停止,结果如图(这里多输出了一 些小数点后数字,其实小数点后只有 6-7 位有效数字):
可见,当 n=2097152=221 时收敛。而这个 n 显然不会造成 1/n 的下溢,因为 1/n 远 远大于 float 能表示的最小正数(约1.5 10
问题 2:通用算法 ........................................................................................................ 4 3.1 Huffman Alike Summation .................................................................................. 4 3.1.1 3.1.2 3.2 理论分析 ................................................................................................. 4 实验结果 ................................................................................................. 5
时, 1/n 的尾数域全部是 0,这时我们就将看到 sum 收敛了。 可以看出,这时的 n=221, 实验结果得到了解释。 返回目录
2.2 Double
有了分析 float 型调和级数收敛的基础,我们可以用类似的方法分析 double 型调和 级数。不过有些不同的是,double 型有 64 个 bit,而且存储方式和 float 不相同: 63 62 52 51 尾数域 0 ]
数据与算法实验报告
Electronics Engineering xxxxx 20xx 年 x 月
数据与算法实验
xxxx
20xx/x
目录
1 2 实验内容描述 ............................................................................................................... 1 问题 1:理论分析 n 的值 ............................................................................................. 1 2.1 2.2 3 Float ................................................................................................................... 1 Double ................................................................................................................ 2
For n:1 to INF temp+=1.0f/n; if n>a*m //a是一个大于 1的实数, a越接近1,精度越高。 sum+=temp; cout<<"n="<<n<<" sum="<<sum<<endl; temp=0; m=n; //n作为 m的新值
这种方法,可以在 n 很大的时候保证每一块的和值是差不多大的,因为根据欧拉公 式,S(n)-S(m)=ln(n/m)=ln(a)。
知,这个时候的
n e1.710 ,它大致为1010 量级。
下溢
324
308
308
如果 1/n 下溢, 粗略看 1/n 应该小于 double 数的最小正数 5.0 10 量级。显然下溢发生在上溢出现之前,收敛原因不会是上溢。 大数吃小数
, 则 n 为10
323
只要分析在下溢发生时, 是否已经发生了大数吃小数的情况即可。 当 n 约为10 级时,sum 约为 sum ln(10
38 45
);收敛和 15.403„„也远远小于最大整
数(约 3.4 10 )不会造成部分求和的上溢,所以只可能是发生了大数吃小数的情况。 下面从理论上分析为什么在 n=221 处收敛。因为 float 型浮点数用 32bit 内存来存储 数据,具体 bit 位分布为
1
数据与算法实验
xxxx
20xx/x
Kahan ................................................................................................................. 6 3.2.1 3.2.2 3.2.3 举例分析 ................................................................................................. 6 理论分析 ................................................................................................. 7 实验结果 ................................................................................................. 7
(2)n=249 时
sum ln(249 ) 0.57721566490 34.5414 26 1 0.00 01 25 253 25 248 n 52个 0 n 248
(3)n=248 时
sum ln(248 ) 0.57721566490 33.8483 26 1 0.00 01 25 253 25 248 n 52个 0 n 248