Fortran Coder

标题: 关于单精度和双精度报错的问题 [打印本页]

作者: sqs    时间: 2022-3-22 21:14
标题: 关于单精度和双精度报错的问题
1. 在用reshape对矩阵进行赋值的时候,为什么会出现我这个地方complex*16报错了呢,而complex却是可以的2. 而且我前面对矩阵中的元素,比如此处的0,进行了定义和赋值,赋值时是双精度复数型的的,为何后面矩阵当中成为了单精度实型的呢。是因为常数吗?

3.那在矩阵当中如何让常数或者所有数据都为双精度呢。
[Fortran] 纯文本查看 复制代码
  real*8 , parameter :: t1 = 3.12 , t2 = 0.29 , t3 = -0.0103
    complex*16 , parameter :: i = (0.0, 1.0) , t0 = (0.0,0.0)
H = reshape([complex*16 :: t0, t1*f1, t0, t0, t0, t0,&
            t1*f2, t0, t0, t2, t0, t3,&
            t0, t0, t0, t1*f2, t0 ,t0,&
            t0, t2, t1*f1,t0, t0, t2, &
            t0, t0, t0, t0, t0, t1*f1,&
            t0, t3, t0, t2, t1*f2, t0],[6 , 6])

报错如下:
[Fortran] 纯文本查看 复制代码
   44 |     H = reshape([complex*16 :: &
      |                         1
Error: Invalid type-spec at (1)

如果去掉complex*16之后便会有以下报错:
45 |             t1*f2, t0, t0, t2, t0, t3,&
      |                          1
Error: Element in COMPLEX(8) array constructor at (1) is REAL(8)




作者: 胡文刚    时间: 2022-3-22 22:05
real*8 , complex*16 这些写法都已被废止。
请用 real(8) complex(8) 代替。

注意,大多数编译器 complex(8) 等效于 complex*16
作者: sqs    时间: 2022-3-23 15:39
胡文刚 发表于 2022-3-22 22:05
real*8 , complex*16 这些写法都已被废止。
请用 real(8) complex(8) 代替。

感谢!我还有个问题,在矩阵内元素的赋值中,比如我对其中一个元素赋值是0.29,但是最后输出的时候却成了0.28999999165534973,请问这是为什么,又应该如何改正呢?
[Fortran] 纯文本查看 复制代码
real(8) , parameter :: t1 = 3.12 , t2 = 0.29 , t3 = -0.0103
H_1 = reshape([complex(8) :: &
            t0, t1*f1, t0, t0, t0, t0,&
            t1*f2, t0, t0, t2, t0, t3,&
            t0, t0, t0, t1*f2, t0 ,t0,&
            t0, t2, t1*f1,t0, t0, t2, &
            t0, t0, t0, t0, t0, t1*f1,&
            t0, t3, t0, t2, t1*f2, t0],[6 , 6])

最后输出的结果是:
   (0.0000000000000000,0.0000000000000000)        (9.3596917284584578,-5.88094530879436223E-002)               (0.0000000000000000,0.0000000000000000)               (0.0000000000000000,0.0000000000000000)               (0.0000000000000000,0.0000000000000000)               (0.0000000000000000,0.0000000000000000)
         (9.3596917284584578,5.88094530879436223E-002)               (0.0000000000000000,0.0000000000000000)               (0.0000000000000000,0.0000000000000000)              (0.28999999165534973,0.0000000000000000)               (0.0000000000000000,0.0000000000000000)        (-1.03000001981854439E-002,0.0000000000000000)
               (0.0000000000000000,0.0000000000000000)               (0.0000000000000000,0.0000000000000000)               (0.0000000000000000,0.0000000000000000)         (9.3596917284584578,5.88094530879436223E-002)               (0.0000000000000000,0.0000000000000000)               (0.0000000000000000,0.0000000000000000)
               (0.0000000000000000,0.0000000000000000)              (0.28999999165534973,0.0000000000000000)        (9.3596917284584578,-5.88094530879436223E-002)               (0.0000000000000000,0.0000000000000000)               (0.0000000000000000,0.0000000000000000)              (0.28999999165534973,0.0000000000000000)
               (0.0000000000000000,0.0000000000000000)               (0.0000000000000000,0.0000000000000000)               (0.0000000000000000,0.0000000000000000)               (0.0000000000000000,0.0000000000000000)               (0.0000000000000000,0.0000000000000000)        (9.3596917284584578,-5.88094530879436223E-002)
               (0.0000000000000000,0.0000000000000000)        (-1.03000001981854439E-002,0.0000000000000000)               (0.0000000000000000,0.0000000000000000)              (0.28999999165534973,0.0000000000000000)         (9.3596917284584578,5.88094530879436223E-002)               (0.0000000000000000,0.0000000000000000)
作者: 胡文刚    时间: 2022-3-23 17:07
本帖最后由 胡文刚 于 2022-3-23 17:10 编辑

real(8) , parameter :: t1 = 3.12_8 , t2 = 0.29_8 , t3 = -0.0103_8

Fortran 的常数也是有 kind 值的。 3.12 在大多数编译器上是单精度的。需要写成 3.12_8 才行。

如果你的代码里,全部的real和complex都是双精度,你可以看看你的编译器是否支持设置为 默认real为双精度。
(主流编译器,比如 intel 和 gfortran 都是可以的,只是操作方法不同)





欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2