2

I generally use this form to get double precision in my Fortran code:

use, intrinsic :: ISO_FORTRAN_ENV
real(kind=real64) :: a = 5d0

However, when defining several variables in a row, real(kind=real64) gets very repetitive. It's tempting to just use real*8, although I've avoided doing so because I've been taught that, although unlikely, it has the potential to make the program non-portable.

From another question I found on the subject I see that real(real64) works, but I don't know if this is good practice; it seems to be the same as using real(8) since, at least on my system, real64 = 8. Is there a shorter way than real(kind=real64) to specify a kind in a variable declaration? Is there even a realistic chance of real*8 causing problems?

zaen
  • 326
  • 3
  • 14
  • Portability isn't really about whether you have `real64` as 8. It's about whether I have as well. And I haven't. But this is a real problem: your `real64` may mean something very different from my `real64` even ignoring the different values. – francescalus Aug 01 '19 at 22:13

1 Answers1

5

The difference between

use, intrinsic :: ISO_FORTRAN_ENV
Real( kind = real64 ) :: a

and

use, intrinsic :: ISO_FORTRAN_ENV
Real( real64 ) :: a

is purely stylistic. Both are equally portable, and are identical as far as the code is concerned. In fact I am having problems understanding why you think they are different. If you think real64 is too long to type you can always use

use, intrinsic :: ISO_FORTRAN_ENV
Integer, Parameter :: wp = real64
Real( wp ) :: a

What is not technically portable is using 5d0 as a constant and assuming it is a real with the same kind as real64. Double precision is obsolete, forget it, rather use the kind mechanism properly with

use, intrinsic :: ISO_FORTRAN_ENV
Integer, Parameter :: wp = real64
Real( wp ) :: a = 5.0_wp
Ian Bush
  • 6,996
  • 1
  • 21
  • 27
  • The question I linked to uses both `integer(kind=RegInt_K)` and `integer(int32)`. I was confused as to why anyone would use the longer version if it weren't necessary, and the form without `kind=` looked like a shortcut similar to `*4`. With your last point, are you saying 5d0 doesn't give you a double precision number? I've never seen it suggested to do something like `5_real64`, which would be much more repetitive than even typing `kind=` on every variable declaration. – zaen Aug 01 '19 at 20:34
  • Firstly 5_real64 is an integer variable of kind real64, at the very least you need 5._real64. Secondly I know of no direct mapping defined by the language of double precision to any kind value. In all honesty 1.0_real64 and 1.0d0 are almost certainly real constants of the same kind, but there is no guarantee. But the real point is 1.0d0 belongs to the 1980s and earlier and should not be being used today. Finally typing _real64 or similar on constants is no major overhead - I suffer from RSI so care about these things, and this is not a bother for me at all. – Ian Bush Aug 01 '19 at 20:44
  • In my case, I'm not so much concerned about RSI as I am about team members on a project I'm a part of rejecting the use of "old, outdated" Fortran in favor of "shiny new" C++ due to quirks like having to do `real(kind=real64) :: a = 5._real64` to get a double precision number instead of `double a = 5;`. Part of the reason I want to use Fortran for this project is its ease of use for things like arrays, and if a simple variable declaration takes that much code, the "easier to use" argument isn't going to go far. Also, it's just plain inefficient to require that much code to specify a double. – zaen Aug 01 '19 at 21:04
  • C is terse by design, Fortran more verbose. C statements tend to do little, Fortran statements can do quite a lot. You pays your money, you takes your choice. And to be honest if the time it takes to type your code is an important consideration, well you are in a very different situation from what I do. – Ian Bush Aug 01 '19 at 22:00
  • 5
    Or `use, intrinsic :: iso_fortran_env, wp=>real64`. – francescalus Aug 01 '19 at 22:05
  • There's no problem with assignment of an integral value of one kind to another. Not to be confused with kind(5d0) likely not to match real64 even though they probably have the same binary form. – tim18 Aug 02 '19 at 12:17
  • Alright, thanks for the advice everybody. I think the best way for me to handle this going forward will be to use @francescalus's suggestion. For multiple-module projects this statement can be put in its own module and that module used instead of iso_fortran_env throughout the project to enable changing precision later on. After doing some research I believe Fortran's kind system isn't comparable to variable declaration in C because a C `double` [is more like a Fortran `DOUBLE PRECISION`](https://en.wikipedia.org/wiki/C_data_types#Basic_types) than a Fortran `real(real64)`. – zaen Aug 02 '19 at 20:01