舍入误差与有效数
1.1 题目
设 S N = ∑ j = 2 N 1 j 2 − 1 S_N=\sum\limits_{j=2}^{N}\displaystyle\frac{1}{j^2-1} SN=j=2∑Nj2−11其精确值为 1 2 ( 2 3 − 1 N − 1 N + 1 ) \displaystyle\frac{1}{2}\left(\frac{2}{3}-\frac{1}{N}-\frac{1}{N+1} \right) 21(32−N1−N+11)
(1) 编写按从大到小的顺序 ( S N = 1 2 2 − 1 + 1 3 2 − 1 + ⋯ + 1 N 2 − 1 ) \left( S_N=\displaystyle\frac{1}{2^{2}-1}+\frac{1}{3^{2}-1}+\cdots+\frac{1}{N^{2}-1} \right) (SN=22−11+32−11+⋯+N2−11)计算 S N S_N SN的通用程序;
(2) 编写按从小到大的顺序 ( S N = 1 N 2 − 1 + 1 ( N − 1 ) 2 − 1 + ⋯ + 1 2 2 − 1 ) \displaystyle\left(S_N=\frac{1}{N^{2}-1}+\frac{1}{(N-1)^{2}-1}+\cdots+\frac{1}{2^{2}-1} \right) (SN=N2−11+(N−1)2−11+⋯+22−11)计算 S N S_N SN的通用程序;
(3) 按上面两种顺序分别计算 S 1 0 2 \rm S_{10^2} S102, S 1 0 4 \rm S_{10^4} S104, S 1 0 6 \rm S_{10^6} S106并指出有效位数(编写程序时用单精度);
(4) 通过本上机题你明白了什么?
1.2 Python源程序
py
import numpy as np
N = input("请输入N的值:")
N = int(N)
Accurate_value = 1 / 2 * (3 / 2 - 1 / N - 1 / (N + 1))
Accurate_value = np.single(Accurate_value)
# 从大到小的顺序 计算S_N
SNl2s = np.single(0)
SNs2l = np.single(0)
# 从小到大的顺序 计算S_N
for n in range(2, N + 1):
SNl2s += np.single(1/(n*n-1))
for m in range(N, 1, -1):
SNs2l += np.single(1/(m*m-1))
print('准确值 SN= {:.8f}'.format(Accurate_value))
print('从大到小的顺序计算值 SN= {:.8f}'.format(SNl2s))
print('从小到大的顺序计算值 SN= {:.8f}'.format(SNs2l))
程序说明
- 由于Python中的变量小数类型只有双精度浮点形式(float),所以采用Numpy库中的
single()
函数将变量类型转换为单精度浮点; - 将准确值、从大到小与从小达到算出的结果 S N \rm S_N SN保留8位小数输出,方便进行比较。
1.3 程序运行结果
请输入N的值:100
准确值 SN= 0.74004948
从大到小的顺序计算值 SN= 0.74004948
从小到大的顺序计算值 SN= 0.74004954
请输入N的值:10000
准确值 SN= 0.74989998
从大到小的顺序计算值 SN= 0.74985212
从小到大的顺序计算值 SN= 0.74989998
请输入N的值:1000000
准确值 SN= 0.74999899
从大到小的顺序计算值 SN= 0.74985212
从小到大的顺序计算值 SN= 0.74999905
表1.1 程序运行结果表
N | 10^2^ | 10^4^ | 10^6^ |
---|---|---|---|
准确值S~N~ | 0.74004948 | 0.74989998 | 0.74999899 |
从大到小的计算值S~N~ | 0.74004948 | 0.74985212 | 0.74985212 |
从小到大的计算值S~N~ | 0.74004954 | 0.74989998 | 0.74999905 |
从大到小的计算值有效位数 | 8 | 5 | 4 |
从小到大的计算值有效位数 | 7 | 8 | 7 |
1.4 结果分析
- 对于一个数值的计算,计算的方法不同得到的结果也不同,计算方法对误差的传播存在一定的影响,数值计算选用合适的方法;
- 对于N为10^2^的运算,从小到大顺序的计算值要比从大到小顺序的计算值有效位数大致相同,推测原因是累加次数较少,两种顺序的计算结果相差不大;
- 对于N为10^4^与10^6^的运算,从大到小的计算顺序出现了"大数吃小数"的现象,计算结果的有效位数出现了降低的现象,后续累加的数都比较小,在相加过程中被大数吃掉,使得结果差距无法在单精度上体现,而从小到大的计算顺序可以一定程度上避免该现象。
- 在今后对此类累加运算的处理尽量采用从小到大顺序进行累加运算。