- 积分
- 852
- 贡献
-
- 精华
- 在线时间
- 小时
- 注册时间
- 2014-2-24
- 最后登录
- 1970-1-1
|
登录后查看更多精彩内容~
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 香酥扇贝 于 2014-4-16 15:54 编辑
先看一个简单的程序:
Program main
implicit none
real::undef=-9999.9,x=-9999.91
print *,undef,x,undef-x
End program
运行之后结果显示:
-9999.900 -9999.910 9.7656250E-03
与理论值0.01相差了0.002还要多……
可见单精度浮点数只能保证6位有效数字以内误差较小,如果程序计算复杂,涉及到非线性计算,累积误差可能变得很大……
通过debug查看一下undef的数值,发现保存的竟然是-9999.90039,莫名其妙多出来 -0.00039……
简单探讨一下原因:现在的32bit浮点数一般遵从IEEE-754标准,存储方式为最高一位为符号位,然后接着是8位指数,最后23位为尾数。
所以的十进制数都是按照二进制展开的,由于尾数位数有限,因此表达精度有限。
例如:9999.9=2^13+2^10+2^9+2^8+2^3+2^2+2^1+2^0+2^(-1)+2^(-2)+2^(-3)+2^(-6)+2^(-7)+2^(-10)+2^(-11)+...
由于float32存储位数有限,从-11次方开始要截断,因此实际值为
2^13+2^10+2^9+2^8+2^3+2^2+2^1+2^0+2^(-1)+2^(-2)+2^(-3)+2^(-6)+2^(-7)+2^(-10)=9999.8994140625
但还不是9999.90039
再看看临近的稍微大点儿的数:
2^13+2^10+2^9+2^8+2^3+2^2+2^1+2^0+2^(-1)+2^(-2)+2^(-3)+2^(-6)+2^(-7)+2^(-9)=9999.900390625
挺像了吧!比较一下,9999.8994140625与9999.9相差了0.0005859375,
而9999.900390625与9999.9则只相差了0.000390625,更加精确,因此编译器也选择了这个数存储~
如果需要获得更高精度的计算,需要使用64bit双精度,在Linux下编译相同的程序时使用命令:ifort -r8 *.f90
但是双精度比较占用资源,如果只是进行一些简单的计算分析,单精度也够用了~
|
评分
-
查看全部评分
|