Evgenii
Evgenii

Reputation: 37329

Is it possible to automatically supply double precision constants in Fortran `data` statement?

I have an array xsolar containing double precision real values:

real*8        xsolar(5)

The array is then filled with numbers using the data statement:

data xsolar/
     . 12.00, 10.93, 1.05, 1.38, 2.70/

By default it looks like the numbers only set the most significant bytes, while the remaining bytes contain random numbers:

12.000000000000000
10.930000305175781
1.0499999523162842
1.3799999952316284
2.7000000476837158

I can fix this problem by writing d0 at the end of the numbers:

data xsolar/
     * 12.00d0, 10.93d0, 1.05d0, 1.38d0, 2.70d0/

which will result in much better precision:

12.000000000000000
10.930000000000000
1.0500000000000000
1.3799999999999999
2.7000000000000002

My problem is that I have a huge list of numbers, not just five. So I have to add d0 to all of them. Can it be done automatically, so all constants in this data statement are treated as if they end with d0? Better yet, can it be done for all my data statements or all real*8 constants?

I'm compiling with gfortran 6.3.0 with flags: -O4 -ffixed-line-length-72 -ff2c.

Upvotes: 1

Views: 589

Answers (1)

Cong Ma
Cong Ma

Reputation: 11302

In general Fortran does make a distinction about single and double precision literals, so 10.93 and 10.93d0 represent quite different objects (See, for example, in this related post).

My suggestion is to look into the gfortran options that enables some (likely non-standard) transformations. According to the manual:

-fdefault-real-8
           Set the default real type to an 8 byte wide type.  Do nothing if
           this is already the default.  This option also affects the kind of
           non-double real constants like 1.0, and does promote the default
           width of "DOUBLE PRECISION" to 16 bytes if possible, unless
           "-fdefault-double-8" is given, too.

-fdefault-double-8
           Set the "DOUBLE PRECISION" type to an 8 byte wide type.  If
           -fdefault-real-8 is given, "DOUBLE PRECISION" would instead be
           promoted to 16 bytes if possible, and -fdefault-double-8 can be
           used to prevent this.  The kind of real constants like "1.d0" will
           not be changed by -fdefault-real-8 though, so also
           -fdefault-double-8 does not affect it.

So indeed it seems likely that you can use both options at the same time, -fdefault-real-8 -fdefault-double-8, to make the literals like 1.0 be taken as 64-bit floating numbers by the compiler. But you have to make sure this is really what you want, and the side effects doesn't affect the rest of the code.

However, since you said you have a big list of numbers, and it's not very likely that you're going to embed them as literals in the code within the data statement, I think it suffices to read them from a file into an array variable already suitably declared.

Upvotes: 2

Related Questions