sqs 发表于 2022-3-22 21:14:28

关于单精度和双精度报错的问题

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

3.那在矩阵当中如何让常数或者所有数据都为双精度呢。
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],)

报错如下:
   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:31

real*8 , complex*16 这些写法都已被废止。
请用 real(8) complex(8) 代替。

注意,大多数编译器 complex(8) 等效于 complex*16

sqs 发表于 2022-3-23 15:39:33

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



感谢!我还有个问题,在矩阵内元素的赋值中,比如我对其中一个元素赋值是0.29,但是最后输出的时候却成了0.28999999165534973,请问这是为什么,又应该如何改正呢?
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],)
最后输出的结果是:
   (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:26

本帖最后由 胡文刚 于 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 都是可以的,只是操作方法不同)
页: [1]
查看完整版本: 关于单精度和双精度报错的问题