# Best way to declare a double precision in Fortran?

**URL:** <https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69>\
**Category:** Help\
**Created:** [May 26, 2020, 7:58am UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69 "2020-05-26T07:58:13Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [May 26, 2020, 7:58am UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/1 "2020-05-26T07:58:13Z")

</div>

Hi,  
there is several ways to declare a double precision real in Fortran:

```
real*8 :: w
real(8) :: x
real(kind(0d0)) :: y
double precision :: z

```

My habits are to use `double precision`. Is it a good practice ?

---

<div class="post-metadata">

**Author:** ![stavros](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@stavros](https://fortran-lang.discourse.group/u/stavros)\
**Post date:** [May 26, 2020, 12:01pm UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/2 "2020-05-26T12:01:07Z")

</div>

The following is more or less, my go-to module that I use it everywhere:

```auto
module mod_types
    use iso_fortran_env, only: int8, int16, int32, int64, real32, real64, &
                                input_unit, output_unit, error_unit
    implicit none
    integer, parameter :: sp = real32
    integer, parameter :: dp = real64
    integer, parameter :: stdin = input_unit
    integer, parameter :: stdout = output_unit
    integer, parameter :: stderr = error_unit
end module

```

An example use is:

```auto
module foo
use mod_types, only: wp=>dp 
implicit none
real(wp)::bar
end module

```

`wp` stands for working precision and if for some reason I want to change precision, I just change this `wp=>sp` so I do not need to change manually all `real` variables. I believe something in that line is considered the “standard way” now.

---

<div class="post-metadata">

**Author:** ![lkedward](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/lkedward/32/72_2.png) [@lkedward](https://fortran-lang.discourse.group/u/lkedward)\
**Post date:** [May 26, 2020, 12:30pm UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/3 "2020-05-26T12:30:08Z")

</div>

I also use the constants defined in `iso_fortran_env`, though I have recently learned (from [this discussion](https://github.com/fortran-lang/stdlib/issues/25) in `stdlib`) that there are still concerns over the portability of these constants since they only guarantee a byte width but nothing about precision.

In his post [“It takes all kinds”](https://stevelionel.com/drfortran/2017/03/27/doctor-fortran-in-it-takes-all-kinds/), Steve Lionel recommends use of the intrinsic function [`selected_real_kind`](https://gcc.gnu.org/onlinedocs/gfortran/SELECTED_005fREAL_005fKIND.html) above all other methods.

It’s also worth mentioning the constants provided by `iso_c_binding` which are required for c interoperability:

```auto
use iso_c_binding, only: sp=>c_float, dp=>c_double

```

---

<div class="post-metadata">

**Author:** ![nncarlson](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/nncarlson/32/1175_2.png) [@nncarlson](https://fortran-lang.discourse.group/u/nncarlson)\
**Post date:** [May 27, 2020, 2:23am UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/4 "2020-05-27T02:23:54Z")

</div>

Note that the `real*8` syntax is an extension and not standard. Also with `real(8)` you are assuming that “real kind 8” is an 8-byte real (which conceivably isn’t even double precision), but there’s nothing in the standard that says kind values correspond to the byte size. In fact with the NAG compiler this isn’t the case. They number their kinds consecutively from 1 (though there is a compiler flag you can use to change that).

---

<div class="post-metadata">

**Author:** ![nncarlson](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/nncarlson/32/1175_2.png) [@nncarlson](https://fortran-lang.discourse.group/u/nncarlson)\
**Post date:** [May 27, 2020, 2:39am UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/5 "2020-05-27T02:39:04Z")

</div>

> [@lkedward](#):
>
> In his post [“It takes all kinds”](https://stevelionel.com/drfortran/2017/03/27/doctor-fortran-in-it-takes-all-kinds/), Steve Lionel recommends use of the intrinsic function [`selected_real_kind`](https://gcc.gnu.org/onlinedocs/gfortran/SELECTED_005fREAL_005fKIND.html) above all other methods.

If one truly knows what decimal precision and exponent range they need for their problem, they can use `selected_real_kind` and let the system decide the kind (and hope it has one). But if you’re like me, all I really know is that the hardware supports 32-bit and 64-bit floating point and that I want to use 64-bit. So in the past I’d figure out a precision and range that would ensure that `selected_real_kind` gave me the 64-bit kind. Thankfully that silliness isn’t needed anymore with the constants from `iso_fortran_env`. I hate to disagree with Steve, but if you know you want a specific fp size, just use the constant and don’t play games with `selected_real_kind`.

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [June 4, 2020, 12:18am UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/6 "2020-06-04T00:18:25Z")

</div>

You can disagree with me, that’s fine. All I wanted to say in that post was that use of real32, real64 etc. was little better than real(4) and real(8). If you’re aware that all you’re doing is asking for a physical storage size (and no other properties), and document that, then OK. But I would be happier to see a module that defines constants using `selected_real_kind()` - you need do this only once.

Of course, if you’re interfacing with C, then use the kinds from `ISO_C_BINDING`.

P.S. Thank you for reading my blog posts!

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [June 4, 2020, 8:02pm UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/7 "2020-06-04T20:02:50Z")

</div>

Thank you all for your valuable answers (and “It Takes All KINDs” was so interesting and pleasant to read). This is a very interesting discussion, I am learning or re-learning many things.

Perhaps using `iso_fortran_env` or `selected_real_kind` depends on the kind of computer scientist you are:

- If you work only on a PC, like myself, `iso_fortran_env` can probably do the job. That kind of machine is relatively stable in time (concerning the reals in the CPU). Although, if GPU acceleration is democratized things can become different. And in 20 years, I don’t know what kind of CPU we will use.
- If you compute on supercomputers, I guess it is more complicated. Your code can run on very different architectures and `selected_real_kind` can surely be very useful. Moreover, you probably work in a bigger team and your code will perhaps still used by other people in 20 years, so keeping the memory of the needed precision will be helpful.

Now, what I am interested in is getting the best compromise between precision and speed. On my PC, I can use 32 bits real, 64 bits, 80 bits, 128 bits:

- but 32 bits is not interesting because I have half the precision of 64 bits with exactly the same computing time. Just a relic from the good old days.
- REAL(10) in gfortran is 80 bits, the computing time is 50% higher but I gain around 5 digits. It can be interesting if I really need a greater precision.
- 128 bits reals doubles the number of digits, but it is not “hardware” (hard wired) reals. It is based on libquadmath and the CPU time is 10 times longer ! Not an option for me…

My question would now be: is it possible with Fortran to know the biggest “hardware” reals offered by the CPU ?

Another question: I thought 80 bits were hard wired, no ? But in that case why the computing time is 50 % higher than with 64 bits reals ?

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [June 4, 2020, 11:32pm UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/8 "2020-06-04T23:32:20Z")

</div>

80-bit floating is only possible with the old x87 instructions. You can’t take advantage of any of the vector SSE or AVX instructions that are generally much faster.

---

<div class="post-metadata">

**Author:** ![lkedward](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/lkedward/32/72_2.png) [@lkedward](https://fortran-lang.discourse.group/u/lkedward)\
**Post date:** [June 5, 2020, 7:46am UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/9 "2020-06-05T07:46:41Z")

</div>

> [@vmagnin](#):
>
> but 32 bits is not interesting because I have half the precision of 64 bits with exactly the same computing time. Just a relic from the good old days.

Since you mention speed, it should be pointed out that there are performance advantages to using 32bit, even though the fundamental operations (+ / \*) are computed in the same time as 64bit:

- Functions implemented with polynomial series will be quicker since fewer terms are needed for the reduced precision;

- If your program can be vectorized, then throughput will be higher with 32bit than 64bit since more values can be placed in the vector registers;

- Many intensive programs are memory-bound these days, so if your program operates on a large-enough dataset (_i.e._ one that doesn’t fit in the cache), and it involves a lot of memory accesses per flop, then you will benefit from ~2x speedup when using 32bit simply by being able to load more values into the processor.

Obviously, these aren’t options if you need double precision (though there are so-called mixed-precision solvers that attempt to exploit this).

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [June 5, 2020, 7:48am UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/10 "2020-06-05T07:48:11Z")

</div>

@sblionel  
Thank you for you explanation. I suspected it was that, but I was surprised that those 80 bits reals works also with `gfortran -mfpmath=sse`. I guess that even with this flag the compiler choose to use x87 when needed.

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [June 5, 2020, 8:05am UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/11 "2020-06-05T08:05:53Z")

</div>

@lkedward  
Thank you very much for you answer, you are right, I was convinced there was no difference, based on arithmetical measurements.  
When computing 2e9 cos(), the 32 bits version is 2.66x times faster than the 64 bits.

Finally, it’s another good reason to adopt a practice like writing `real(wp)::bar`. By just changing the `wp` value I could study the difference in computing time.

---

<div class="post-metadata">

**Author:** ![gardhor](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/gardhor/32/88_2.png) [@gardhor](https://fortran-lang.discourse.group/u/gardhor)\
**Post date:** [June 14, 2020, 8:09am UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/12 "2020-06-14T08:09:59Z")

</div>

Hi everyone,

About the nag compiler, you’re right, kind=8 is not working with the default option. However, when the “-kind=byte” option is used, old codes (and new ones) can be compile with real\*8 or real (kind=8).

---

<div class="post-metadata">

**Author:** ![jacobwilliams](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/jacobwilliams/32/10_2.png) [@jacobwilliams](https://fortran-lang.discourse.group/u/jacobwilliams)\
**Post date:** [April 12, 2022, 8:46pm UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/13 "2022-04-12T20:46:43Z")

</div>

Why does this have to be so complicated? (it’s a rhetorical question…I know how we got here).

But the fact is, this is all very confusing for beginners and people coming from other languages. This is why every day on stack overflow we see questions about why isn’t this working right:

```fortran
real*8 pi = 3.14159265358979323

```

Making people have to use `iso_fortran_env` or `selected_real_kind` just to declare a real number is just user-hostile. Nobody wants to type all that (hence `real*8`).

Is there nothing that can be done about it?

In most other languages that people might come to Fortran from, double precision is the default. Can we just make double precision the default in Fortran? I feel like that would fix 80% of the problems people have.

---

<div class="post-metadata">

**Author:** ![msz59](https://avatars.discourse-cdn.com/v4/letter/m/3d9bf3/32.png) [@msz59](https://fortran-lang.discourse.group/u/msz59)\
**Post date:** [April 12, 2022, 8:50pm UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/14 "2022-04-12T20:50:36Z")

</div>

> [@jacobwilliams](#):
>
> Is there nothing that can be done about it?

It was said many times. If one hates iso-s and kinds, one can still write  
DOUBLE PRECISION x=3.14159265358979323d0

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [April 12, 2022, 8:55pm UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/16 "2022-04-12T20:55:43Z")

</div>

> [@jacobwilliams](#):
>
> Why does this have to be so complicated? (it’s a rhetorical question…I know how we got here).
> 
> But the fact is, this is all very confusing for beginners and people coming from other languages. This is why every day on stack overflow we see questions about why isn’t this working right:
> 
> ```fortran
> real*8 pi = 3.14159265358979323
> 
> ```
> 
> Making people have to use `iso_fortran_env` or `selected_real_kind` just to declare a real number is just user-hostile. Nobody wants to type all that (hence `real*8`).
> 
> Is there nothing that can be done about it?
> 
> In most other languages that people might come to Fortran from, double precision is the default. Can we just make double precision the default in Fortran? I feel like that would fix 80% of the problems people have.

On comp.lang.fortran I asked if we can [Standardize real\*8 as real(kind=real64)?](https://groups.google.com/g/comp.lang.fortran/c/baaS4bgjmJg) There was not much support for doing so. I don’t think making double precision the default is feasible, because it would break the codes calling procedures with single precision dummy arguments where the actual argument is a literal such as 3.14159265358979323.

---

<div class="post-metadata">

**Author:** ![msz59](https://avatars.discourse-cdn.com/v4/letter/m/3d9bf3/32.png) [@msz59](https://fortran-lang.discourse.group/u/msz59)\
**Post date:** [April 12, 2022, 9:20pm UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/17 "2022-04-12T21:20:14Z")

</div>

Note, also, that the _C world_ is not that-better. Indeed, the literal FP constants in C default to `double` but it is only because the pre-ANSI C did all FP arithmetic in double precision. But then if you want to define a `long double` value, you have to add `L` suffix, otherwise it will get truncated to `double` precision _before_ being assigned to `long double` variable.  
PS. for some reason, this is not the case with integer C literal constants, for which the compiler assigns the first (“shortest”, starting from `int`) type which contains the value.

---

<div class="post-metadata">

**Author:** ![gnikit](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/gnikit/32/1213_2.png) [@gnikit](https://fortran-lang.discourse.group/u/gnikit)\
**Post date:** [April 12, 2022, 10:16pm UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/18 "2022-04-12T22:16:28Z")

</div>

> [@jacobwilliams](#):
>
> Why does this have to be so complicated? (it’s a rhetorical question…I know how we got here).
> 
> But the fact is, this is all very confusing for beginners and people coming from other languages. This is why every day on stack overflow we see questions about why isn’t this working right:
> 
> ```auto
> real*8 pi = 3.14159265358979323
> 
> ```
> 
> Making people have to use `iso_fortran_env` or `selected_real_kind` just to declare a real number is just user-hostile. Nobody wants to type all that (hence `real*8` ).
> 
> Is there nothing that can be done about it?
> 
> In most other languages that people might come to Fortran from, double precision is the default. Can we just make double precision the default in Fortran? I feel like that would fix 80% of the problems people have.

I am pretty sure that because there are multiple ways of defining types in Fortran and people are unsure as to which on is “the correct one”, my research group eventually gave up and are using the way more satanic flags `-fdefault-real-8` and `-fdefault-double-8`

---

<div class="post-metadata">

**Author:** ![CRquantum](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/crquantum/32/730_2.png) [@CRquantum](https://fortran-lang.discourse.group/u/CRquantum)\
**Post date:** [April 12, 2022, 10:50pm UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/19 "2022-04-12T22:50:45Z")

</div>

> [@jacobwilliams](#):
>
> Why does this have to be so complicated? (it’s a rhetorical question…I know how we got here).
> 
> But the fact is, this is all very confusing for beginners and people coming from other languages. This is why every day on stack overflow we see questions about why isn’t this working right:
> 
> ```auto
> real*8 pi = 3.14159265358979323
> 
> ```
> 
> Making people have to use `iso_fortran_env` or `selected_real_kind` just to declare a real number is just user-hostile. Nobody wants to type all that (hence `real*8` ).
> 
> Is there nothing that can be done about it?
> 
> In most other languages that people might come to Fortran from, double precision is the default. Can we just make double precision the default in Fortran? I feel like that would fix 80% of the problems people have.

That is great comment 🙂

Intel Fortran can add flags to define the size of default integer, real, double precision,

 ![image](https://global.discourse-cdn.com/free1/uploads/fortran_lang/original/2X/5/5ebb6b6f51eefc5cd15c91ac06ae463c00dddca7.png)

gfortran can easily do such things too, as @gnikit pointed out.

---

<div class="post-metadata">

**Author:** ![fortran4r](https://avatars.discourse-cdn.com/v4/letter/f/9de0a6/32.png) [@fortran4r](https://fortran-lang.discourse.group/u/fortran4r)\
**Post date:** [April 12, 2022, 10:53pm UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/20 "2022-04-12T22:53:22Z")

</div>

> [@jacobwilliams](#):
>
> ```auto
> real*8 pi = 3.14159265358979323
> 
> ```

I like this style.

`real(8) :: pi = 3.14159265358979323d0`

---

<div class="post-metadata">

**Author:** ![CRquantum](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/crquantum/32/730_2.png) [@CRquantum](https://fortran-lang.discourse.group/u/CRquantum)\
**Post date:** [April 13, 2022, 12:26am UTC](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69/21 "2022-04-13T00:26:22Z")

</div>

> [@fortran4r](#):
>
> I like this style.
> 
> `real(8) :: pi = 3.14159265358979323d0`

I do the following,

```auto
integer, parameter :: r8=selected_real_kind(15,9)
real(kind=r8), parameter :: pi=4.0_r8*atan(1.0_r8) 

```

[Next page](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69.md?page=2)
