回 帖 发 新 帖 刷新版面

主题:请教关于fortran双精度的问题

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个回复)

沙发

至少我的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

呵呵, 明白了吧?

板凳

继续.

如果用一个单精度常数来初始化双精度变量, 结果是什么样呢?
这里我选择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 楼

恩,太感谢了。
看来要严格按照双精度计算,写代码的时候还是要留心的。

4 楼

再问一个,如果在程序当中写成
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 楼

平方指数必须写成2, 而不是2.0, 否则速度相差很大. 编译器会把平方处理成x*x, 即相乘.

6 楼

我的习惯也是写成0.1d0,以前没多想,因为看到程序里都这么写,今天看到原因了。

7 楼

请问这个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 楼

gfortran是linux下面的fortran的编译器。不过你在windows下面内存不够,换了linux系统,我猜也是一样的结果。
多谢f2003的解答。

我来回复

您尚未登录,请登录后再回复。点此登录或注册