主题:[讨论]求教一个双精度的问题
casyang
[专家分:0] 发布于 2010-09-15 13:39:00
输入如下
real*8:: A=1.0d-11
输出A的值为 9.999999999999999E-012,这不是A的真实值
A的真实值是 1.000000000000000E-011
如果运行
real*8:: dt=0.1d-12
real*8 A
A=100*dt
输出的A值就是 1.000000000000000E-011
最后更新于:2010-09-15 23:22:00
回复列表 (共15个回复)
11 楼
casyang [专家分:0] 发布于 2010-09-16 09:00:00
我奇怪的是为什么只有 1.0d-11不能显示准确值,其他的都可以
12 楼
adda [专家分:1520] 发布于 2010-09-16 12:29:00
上午闲来无事,调试了一把。
real(8) :: a = 1d-11
real(8) :: b = 0.1d-10
real(8) :: c
c = 100 * b
print *, a, c
输出值为
9.999999999999999E-012
1.000000000000000E-011
1d-11的精确值应为 0.687194767360000 * 2 ** -36,
其小数位 0.687194767360000 不能被准确表示。
调试程序,a在内存中为 0x3DA5FD7FE1796495,c为3DA5FD7FE1796496
根据IEEE标准,real(8)在内存中由64bit组成,其中第63位是符号位,第62到第52位是指数部分,第51到第0位是小数部分。
a、c的小数部分分别是
0101111111010111111111100001011110010110010010010101
0101111111010111111111100001011110010110010010010110
其值依次为
0.687194767359999958422633881127695...
0.687194767360000069444936343643349...
a的小数部分更接近准确值 0.687194767360000,
因此,对于1d-11,a是比c更精确的表示,尽管c“看起来更准确”
总之,对一般的数值计算,追求浮点数的最后一两位的准确是没意义的,需要更高精度的话应该用更长的字长
13 楼
jstzhurj [专家分:4680] 发布于 2010-09-16 12:41:00
我也试了一下:
对于1.0E-11与1.0E-013在计算机中四倍精度,双精度的二进制表示如下。实际上对于这两个数,用二进制是无法精确表示的(无限循环),无论是四倍精度还是双精度的二进制表示,最后一位有效数字都进行了0舍1入(比较四倍精度,双精度数可以明显看出0舍1入),就看舍弃的或是进位的谁更接近真实值。
1.0E-11
00111111110110100101111111010111111111100001011110010110010010010101010111111101111011110001111011010011010010100010101001110100
0011110110100101111111010111111111100001011110010110010010010101
1.0E-013
00111111110100111100001001011100001001101000010010010111011010000001110000100110010100001100101101001011111001000000110101100001
0011110100111100001001011100001001101000010010010111011010000010
14 楼
jstzhurj [专家分:4680] 发布于 2010-09-16 13:17:00
修改程序如下:
PROGRAM main
implicit none
integer(KIND=2),parameter::K=16
real(KIND=K)::a,b,c,dt
a=0.00000000001_k
dt=0.0000000000001_k
c=100.0_k
b=c*dt
write(*,*) a,b
END PROGRAM
得到运行结果: 1.000000000000000000000000000000000E-0011
1.000000000000000000000000000000000E-0011,所以虽然4倍精度数对最后有效位进行了舍入,但基本上还是接近真实值的!4倍精度就是比双精度精确些!废话!(⊙o⊙)嗯!
15 楼
casyang [专家分:0] 发布于 2010-09-17 05:28:00
了解了,谢谢jstzhurj和adda的帮助
我昨天在matlab里面试了一下,在双精度的情况下,
matlab中的1d-11其实也是9.999999999999999E-012这个值,看来正如adda所说的,其实后者才是更精确的显示。
我来回复