主题:请教关于fortran双精度的问题
luzheng111 [专家分:30] 发布于 2009-04-30 17:22:00
real(kind=8)a,b
a=0.5
b=0.1*a
end
这里a,b都是双精度,但是b赋值的时候用了0.1*,这个0.1默认下是单精度的,那是不是说这个计算也就是单精度了呢?因为我看了b的值,出来的也是双精度的。
我估计b的计算的时候是单精度,但是算完以后又转换成了双精度(因为定义b是双精度),所以如果要一直都是双精度计算的话,b应该写为b=0.1d0*a,是这样吗?
请知道的人帮忙说一下。
还有一个问题,双精度的计算会影响fortran的运算速度吗?
回复列表 (共8个回复)
沙发
f2003 [专家分:7960] 发布于 2009-04-30 19:07:00
至少我的gfortran是这样.
program main
implicit none
real(8) :: a,b
a=0.5
b=0.1*a
continue
end program main
我增加了一行continue, 在那里设置断点, 运行到那一行中断, 我查看a,b的值,结果是:
d1.<> dprint a
a = 0.5
d1.<> dprint b
b = 0.0500000007450581
严格地保持双精度要求a的赋值写成a=0.5d0 或者a=0.5_8 , 但a很幸运,因为0.5等于1/2,可以用二进制小数没有任何误差地精确表示, 从而是一个ieee浮点数, 对于这种情形, 单精度/双精度都一样.
但b就没有那么幸运了,结果显然是单精度0.1乘以a的结果.
我把程序修改一下,
program main
implicit none
real(8) :: a,b
a=0.5
b=0.1d0*a
continue
end program main
结果:
d1.<> dprint a
a = 0.5
d1.<> dprint b
b = 0.05
呵呵, 明白了吧?
板凳
f2003 [专家分:7960] 发布于 2009-04-30 19:18:00
继续.
如果用一个单精度常数来初始化双精度变量, 结果是什么样呢?
这里我选择0.1, 0.1不能用有限位二进制精确表示, 小数点后是无限循环的.
program main
implicit none
real(8) :: a
a=0.1
continue
end program main
调试结果看看吧,
d1.<> dprint a
a = 0.100000001490116
程序改成将双精度0.1赋值给a,
program main
implicit none
real(8) :: a
a=0.1_8
continue
end program main
结果是:
d1.<> dprint a
a = 0.1
其实这个问题大家以前已经讨论清楚了, 结论是显然的. 今天,我用了个实际例子表演了一下.
3 楼
luzheng111 [专家分:30] 发布于 2009-05-01 03:26:00
恩,太感谢了。
看来要严格按照双精度计算,写代码的时候还是要留心的。
4 楼
luzheng111 [专家分:30] 发布于 2009-05-01 04:21:00
再问一个,如果在程序当中写成
implicit none
real(kind=8) a,b,c
a=0.1d0
b=2*a
c=a**2
end
这里b,c赋值时,2是当作整型还是单精度浮点数呢?
应该写成b=2d0*a; c=a**2d0吗?
搜了论坛里面关于双精度的帖子,但是还是不确认,所以还是再上来问问,多谢拉~
5 楼
f2003 [专家分:7960] 发布于 2009-05-01 09:46:00
平方指数必须写成2, 而不是2.0, 否则速度相差很大. 编译器会把平方处理成x*x, 即相乘.
6 楼
chengw1976 [专家分:130] 发布于 2009-05-01 09:58:00
我的习惯也是写成0.1d0,以前没多想,因为看到程序里都这么写,今天看到原因了。
7 楼
chengw1976 [专家分:130] 发布于 2009-05-01 10:01:00
请问这个gfortran是linux下的fortran吗,有什么优势吗,能不能给科普一下。我现在用windows支持的CVF,可是程序需要的内存太大,我的2G的内存都不够了,昨天出现了执行不了的状况,就是按了ctr+f5 一点反应也没有。谢谢了。
[quote]至少我的gfortran是这样.
program main
implicit none
real(8) :: a,b
a=0.5
b=0.1*a
continue
end program main
我增加了一行continue, 在那里设置断点, 运行到那一行中断, 我查看a,b的值,结果是:
d1.<> dprint a
a = 0.5
d1.<> dprint b
b = 0.0500000007450581
严格地保持双精度要求a的赋值写成a=0.5d0 或者a=0.5_8 , 但a很幸运,因为0.5等于1/2,可以用二进制小数没有任何误差地精确表示, 从而是一个ieee浮点数, 对于这种情形, 单精度/双精度都一样.
但b就没有那么幸运了,结果显然是单精度0.1乘以a的结果.
我把程序修改一下,
program main
implicit none
real(8) :: a,b
a=0.5
b=0.1d0*a
continue
end program main
结果:
d1.<> dprint a
a = 0.5
d1.<> dprint b
b = 0.05
呵呵, 明白了吧?[/quote]
8 楼
luzheng111 [专家分:30] 发布于 2009-05-01 15:19:00
gfortran是linux下面的fortran的编译器。不过你在windows下面内存不够,换了linux系统,我猜也是一样的结果。
多谢f2003的解答。
我来回复