主题:[讨论]求教一个双精度的问题
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个回复)
沙发
jstzhurj [专家分:4680] 发布于 2010-09-15 13:55:00
你什么编译器?
我用cvf6.6 输出分别是9.999999999999999E-012 9.999999824516700E-012
板凳
jstzhurj [专家分:4680] 发布于 2010-09-15 14:24:00
运算越多,累计误差越大,不应该出现你这种情况。
3 楼
casyang [专家分:0] 发布于 2010-09-15 22:28:00
我的编译器是vs2008 + ivf
程序里只有这一个语句,没有其他的运算,不存在误差累积
在另一台电脑上vs2003+ivf, 结果还是一样
4 楼
jstzhurj [专家分:4680] 发布于 2010-09-15 22:48:00
我也用ivf编译了,结果和cvf6.6输出一样!都是9.999999999999999E-012 9.999999824516700E-012,真是怪事,不知道其他网友结果是否一致?
代码如下:
PROGRAM main
implicit none
integer(KIND=2),parameter::K=8
real(KIND=K)::a=1.0d-11,b
real(KIND=K)::dt=0.1e-12
b=100*dt
write(*,*) a,b
END
5 楼
casyang [专家分:0] 发布于 2010-09-15 23:08:00
我又用gfortran 试了一下
代码:
program test
implicit none
real*8:: dt=0.1d-12, b=1.0d-11, A
A=100*dt
write(*,*)b
write(*,*)A
end
结果
9.999999999999999E-012
1.000000000000000E-011
还是一样的,不会是我电脑的问题吧?
6 楼
casyang [专家分:0] 发布于 2010-09-15 23:13:00
[quote]
我也用ivf编译了,结果和cvf6.6输出一样!都是9.999999999999999E-012 9.999999824516700E-012,真是怪事,不知道其他网友结果是否一致?
代码如下:
PROGRAM main
implicit none
integer(KIND=2),parameter::K=8
real(KIND=K)::a=1.0d-11,b
real(KIND=K)::dt=0.1e-12
b=100*dt
write(*,*) a,b
END
[/quote]
你的b的值不对是因为你的dt=0.1e-12 是单精度的,应该是dt=0.1d-12,这样b的结果就是1.000000000000000E-011。
7 楼
jstzhurj [专家分:4680] 发布于 2010-09-16 00:04:00
我晕,你最初给的是dt=0.1e-12,现在又改成dt=0.1d-12!
改成
PROGRAM main
implicit none
integer(KIND=2),parameter::K=8
real(KIND=K)::a=1.0d-11,b
real(KIND=K)::dt=0.1d-12
b=100*dt
write(*,*) a,b
END
得到与你一致的结果:9.999999999999999E-012 1.000000000000000E-011
8 楼
jstzhurj [专家分:4680] 发布于 2010-09-16 00:56:00
应该是浮点数的二进制表示问题
不妨改成4倍精度的数来看一下,比较只输出16位有效数字和默认有效位的结果差异,或许能看出其中的玄机。
PROGRAM main
implicit none
integer(KIND=2),parameter::K=16
real(KIND=K)::a=1.0d-11,b,c=100.,dt=0.1d-12
b=c*dt
write(*,'((e30.16))') a,b,c,dt
write(*,*) a,b,c,dt
END
END
9 楼
casyang [专家分:0] 发布于 2010-09-16 02:47:00
[quote]应该是浮点数的二进制表示问题
不妨改成4倍精度的数来看一下,比较只输出16位有效数字和默认有效位的结果差异,或许能看出其中的玄机。
PROGRAM main
implicit none
integer(KIND=2),parameter::K=16
real(KIND=K)::a=1.0d-11,b,c=100.,dt=0.1d-12
b=c*dt
write(*,'((e30.16))') a,b,c,dt
write(*,*) a,b,c,dt
END
END[/quote]
按照这个试了一下,还是无法输出a的准确值。
10 楼
adda [专家分:1520] 发布于 2010-09-16 08:24:00
[quote][quote]应该是浮点数的二进制表示问题
不妨改成4倍精度的数来看一下,比较只输出16位有效数字和默认有效位的结果差异,或许能看出其中的玄机。
PROGRAM main
implicit none
integer(KIND=2),parameter::K=16
real(KIND=K)::a=1.0d-11,b,c=100.,dt=0.1d-12
b=c*dt
write(*,'((e30.16))') a,b,c,dt
write(*,*) a,b,c,dt
END
END[/quote]
按照这个试了一下,还是无法输出a的准确值。
[/quote]
a的准确值就那么重要吗?既然用浮点数了,就应该预计到可能存在的舍入误差
我来回复