Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Standardize real*8 as real(kind=real64)?

864 views
Skip to first unread message

Beliavsky

unread,
Apr 9, 2022, 10:05:29 AM4/9/22
to
Since compilers treat the non-standard but very common

real*4, real*8, integer*4, integer*8

as

use iso_fortran_env
real(kind=real32), real(kind=real64), integer(kind=int32), integer(kind=int64)

would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?

Beliavsky

unread,
Apr 9, 2022, 10:37:41 AM4/9/22
to
Currently, if someone inherits a code with real*8 and decides to make it standard-conforming, they may replace it with
real(kind=8), which is not guaranteed to work (failing with the NAG compiler for example). By standardizing real*8 appropriately this error is avoided.

Robin Vowels

unread,
Apr 9, 2022, 10:55:40 AM4/9/22
to
On Sunday, April 10, 2022 at 12:37:41 AM UTC+10, Beliavsky wrote:
> On Saturday, April 9, 2022 at 10:05:29 AM UTC-4, Beliavsky wrote:
> > Since compilers treat the non-standard but very common
> >
> > real*4, real*8, integer*4, integer*8
> >
> > as
> >
> > use iso_fortran_env
> > real(kind=real32), real(kind=real64), integer(kind=int32), integer(kind=int64)
> >
> > would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?
> Currently, if someone inherits a code with real*8 and decides to make it standard-conforming, they may replace it with
> real(kind=8),
.
An appropriate replacement is real (kind=dp)
which is one character more than the non-portable form you just suggested.
(where dp is defined as kind(1.0d0) or something equivalent specifying a number of digits )
.
> which is not guaranteed to work (failing with the NAG compiler for example).
> By standardizing real*8 appropriately this error is avoided.
.
real*8 has never been standard.

FortranFan

unread,
Apr 9, 2022, 11:39:15 AM4/9/22
to
On Saturday, April 9, 2022 at 10:05:29 AM UTC-4, Beliavsky wrote:
> ..
> would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?

No.

gah4

unread,
Apr 9, 2022, 12:08:56 PM4/9/22
to
On Saturday, April 9, 2022 at 7:05:29 AM UTC-7, Beliavsky wrote:
(snip)

> would it make sense to standardize the former set of declarations,
> which is concise and clear, to mean the same as the latter?

One thing that I have long thought, is that it would be nice to include in the
standard some things that aren't required of implementations, but indicate
how to do something if it is included.

(And more generally than this question.)

In the past, this was complicated by machines with 60 or 64 bit words,
that had a type of that length as default REAL, and then (as required by
the standard) a longer type of DOUBLE PRECISION. Those machines are
now out of favor.

On the other hand, the IEEE 754-2008 decimal floating point has
the 64 bit and 128 bit forms as basic types. I suspect that a Fortran
compiler implementing those would use them as the single and
double precision types. (The 32 bit form has about the same status
as the 16 bit binary form.)

There are many deprecated features that it would be very easy to write
a program to convert to non-deprecated form. As far as I know, that hasn't
been done. (And in both free and fixed form.)

I do find it interesting that the Fortran II PRINT statement, after not making
it into Fortran 66, later was included in the standard. Including REAL*8 makes
about as much sense.

gah4

unread,
Apr 9, 2022, 12:16:46 PM4/9/22
to
On Saturday, April 9, 2022 at 7:37:41 AM UTC-7, Beliavsky wrote:

(snip)

> Currently, if someone inherits a code with real*8 and decides to make it
> standard-conforming, they may replace it with real(kind=8), which is not
> guaranteed to work (failing with the NAG compiler for example).

> By standardizing real*8 appropriately this error is avoided.

As far as I know, REAL(8) is more popular, and equally standard and
non-portable.

I even knew of a MOOC, meant for introducing Fortran to physicists,
that taught REAL(8).

REAL(KIND(1D0))

would be standard, and reliably give a double precision type, though takes
more characters to type.

It is nice to have something that can be replaced, line by line, without the
need for any other lines to be included. (Well, assuming appropriate
continuation rules.)

Beliavsky

unread,
Apr 9, 2022, 12:46:13 PM4/9/22
to
On Saturday, April 9, 2022 at 12:16:46 PM UTC-4, gah4 wrote:
> As far as I know, REAL(8) is more popular, and equally standard and
> non-portable.
>
> I even knew of a MOOC, meant for introducing Fortran to physicists,
> that taught REAL(8).
>
> REAL(KIND(1D0))
>
> would be standard, and reliably give a double precision type, though takes
> more characters to type.
>
> It is nice to have something that can be replaced, line by line, without the
> need for any other lines to be included. (Well, assuming appropriate
> continuation rules.)

If someone declares variables as real*8 they are saying that 8-byte reals are sufficient.
You could have a platform where singe precision is real(kind=real64) and double
precision is real(kind=real128). In that case the natural equivalent of real*8 would be
real(kind=real128) and not real(kind=kind(1.0d0)).

Ron Shepard

unread,
Apr 9, 2022, 1:15:45 PM4/9/22
to
In my opinion, this would be a step backward for the language.

There are many reasons why this should not be done, but one of them is
that REAL*4 etc. were always just defined by the local compiler to map
to its supported floating point formats. For byte addressable machines,
that meant that your suggested mapping would be correct. But there are
also 36-bit, 60-bit, and 64-bit machines that cannot conform to those
mappings, so they must do something different. In the f77 time in the
1980s, I used those declarations extensively for exactly that reason, it
was a way, with some care, to write portable (but nonstandard) code. I
used REAL*8 declarations to run on machines with all of those word
lengths. It wasn't pretty, but it served its purpose at the time.

But now we have the fortran KIND system, which handles all of that much
better. Yes, when you incorporate old f66 and f77 code into your current
project, you need to edit in those changes, but that is not a big deal.
Your minimal efforts are rewarded with clarity and portability. I have
programs with hundreds of thousands of lines where I can change the
precision globally by modifying a single line of code in a module. From
the programmer's perspective, that is hard to beat.

Numerical analysts are now experimenting with 16-bit real arithmetic to
speed up critical parts of algorithms. If/when they get that working,
the fortran KIND system is already set up to handle that. IEEE decimal
arithmetic is another feature raising its head on the horizon. Again,
the fortran KIND system is already there and waiting. 10-byte arithmetic
is another example (although some compilers are currently doing this the
wrong way, I think). 128-bit arithmetic and beyond, both reals and
integers, are all handled perfectly well with the fortran KIND system.

If a compiler supports real types with those numbers of bits (real32,
real64, etc.), then the kind values are set appropriately. If there is
more than one kind with that many bits, then the processor chooses which
one to return. If the processor does not support a kind with exactly
those bits, then the processor sets the value to either -1 or -2. The -2
value means that some kind is available with higher precision. This
might not be the best way to write portable code, but if you want to
write code targeted to specific floating point formats, that is a
reasonable way to do it. The IEEE intrinsic module goes even further if
code is intended to target that floating point format, rounding modes,
NaN, subnormals, etc., all available within the fortran KIND system.
This is all in contrast to REAL*4, REAL*8, etc, which are mapped in a
very loose manner to the underlying supported floating point formats.

I think the fortran KIND system is well thought out and it works well in
practice. An improvement might be to eliminate shared KIND values
between different types -- that is a sometimes subtle source of code
errors. Another improvement might be the ability to write generic
subprograms that automatically accommodate all supported KINDs of arguments.

$.02 -Ron Shepard
Message has been deleted

John Collins

unread,
Apr 9, 2022, 2:19:23 PM4/9/22
to
I am in favour of making this standard, but I think it is academic. I know of no compilers in common use which do not support declarations in this format, and I doubt if any compiler writers would remove them for the sake of annoying some of their users.

The KIND specifications are clear and unambiguous, but in small test programs they can take up a significant proportion of the entire text.

John Collins

unread,
Apr 9, 2022, 2:32:51 PM4/9/22
to
>
> There are many deprecated features that it would be very easy to write
> a program to convert to non-deprecated form. As far as I know, that hasn't
> been done. (And in both free and fixed form.)
>
> I do find it interesting that the Fortran II PRINT statement, after not making
> it into Fortran 66, later was included in the standard. Including REAL*8 makes
> about as much sense.

We have tried to convert a large number of legacy constructs to standard form in fpt (http://simconglobal.com). This includes changing REAL*n to the appropriate kind (Or back again for migration projects where you need to retest on the original host :-) ).

Changing REAL*n, INTEGER*n etc. was easy but some of the conversions were NOT "very easy to write".

FortranFan

unread,
Apr 9, 2022, 2:40:46 PM4/9/22
to
On Saturday, April 9, 2022 at 2:19:23 PM UTC-4, john.c...@simconglobal.com wrote:

> ..
> I am in favour of making this standard ..
> The KIND specifications are clear and unambiguous, but in small test programs they can take up a significant proportion of the entire text.

Should the standard do anything now, a better option will be to simply provide built-in i.e., ALIASes toward type-and-kind equivalent to certain standard floating point formats, say IEEE binary (and perhaps decimal) formats.

For the foreseeable future, the powers-that-be in the industry and research and engineering areas I know only expect to use IEEE binary 64-bit floating point in >99% of computing.

So what will be really useful is to have, say, IEEE_FPB64 as an alias for real(KIND=xx) where xx is IEEE_SELECTED_REAL_KIND( p=, r=, radix=..) corresponding to 64-bit IEEE binary floating point format.

One should then be able to do the following in any processor that provides support for IEEE_xxx features from Fortran 2003+ which is several of the modern Fortran compilers:

ieee_fpb64 :: x

One can combine that with proposal for kinds for literal constants.

Thomas Koenig

unread,
Apr 9, 2022, 5:29:37 PM4/9/22
to
gah4 <ga...@u.washington.edu> schrieb:
> On Saturday, April 9, 2022 at 7:05:29 AM UTC-7, Beliavsky wrote:
> (snip)
>
>> would it make sense to standardize the former set of declarations,
>> which is concise and clear, to mean the same as the latter?
>
> One thing that I have long thought, is that it would be nice to include in the
> standard some things that aren't required of implementations, but indicate
> how to do something if it is included.
>
> (And more generally than this question.)
>
> In the past, this was complicated by machines with 60 or 64 bit words,
> that had a type of that length as default REAL, and then (as required by
> the standard) a longer type of DOUBLE PRECISION. Those machines are
> now out of favor.

POWER has rather recently acquired IEEE quad precision, and
gfortran will have aquired support for it in the upcoming
release.

Not as double precision, but as REAL(KIND=16).

JCampbell

unread,
Apr 10, 2022, 1:35:25 AM4/10/22
to
real*8 and real(kind=real64) both provide a clear documentation of precision.
real(8) unfortunately, is not portable.

real(dp) or real(kind=dp) is not clear, as you need to search for the definition of dp, often in a "remote" module.
sp, dp, qp, wp, r4 or r8 are not standard abbreviations. They are not uncommon real variables in legacy codes.

I use multiple compilers, which have different kind values. Real*8 works easily for me on all compilers I use, while real(kind=dp) has the problem of which compiler last compiled the module where DP was defined.
One compiler has real_kinds of [ 1,2 ] and integer_kinds of [ 1,2,3,4 ]. Try using integers such as 123_4 and see what you get for the different compilers I use.

When using real*8, there is always the danger of using a compiler that does not support this non-standard syntax. I think there are greater dangers out there at the moment!
I have used new Fortran compilers that did not support the real*byte syntax. It has happened a few times and I always successfully lobbied for the compiler to be enhanced.
Most new OS and compilers tend to want to help established users.

IEEE documents also use REAL*8 syntax.

gah4

unread,
Apr 10, 2022, 3:34:42 AM4/10/22
to
On Saturday, April 9, 2022 at 2:29:37 PM UTC-7, Thomas Koenig wrote:
> gah4 <ga...@u.washington.edu> schrieb:
> > On Saturday, April 9, 2022 at 7:05:29 AM UTC-7, Beliavsky wrote:

(snip)

> > In the past, this was complicated by machines with 60 or 64 bit words,
> > that had a type of that length as default REAL, and then (as required by
> > the standard) a longer type of DOUBLE PRECISION. Those machines are
> > now out of favor.

> POWER has rather recently acquired IEEE quad precision, and
> gfortran will have aquired support for it in the upcoming
> release.

It was the word addressed 60 and 64 bit machines that didn't have
a smaller floating point type. IBM had REAL*16 and COMPLEX*32
since the 360/85 and standard on all S/370 and later models.

I am surprised it took this long to get to POWER.

VAX Fortran also supports REAL*16 and COMPLEX*32, though
software emulated on many machines. That was from close
to the beginning of VAX. (A microcode option on most,
it was standard on the low end 11/730.)

> Not as double precision, but as REAL(KIND=16).

As long as it supports a 32 bit, more or less, type, that isn't
a problem. But the Fortran standard requires, or at least used to,
a double precision twice (more or less) single precision.

But as I noted, for the IEEE 754-2008 decimal float types,
the basic types are 64 and 128 bit.

A Fortran compiler implementing only those, would call them single
and double precision. I believe the later POWER machines support those,
in addition to the binary forms. I would be surprised if someone wrote
a Fortran compiler for POWER supporting only the decimal types.

Note, though, that the DEC compilers for the 36 bit PDP-10
recognize REAL*8 for the 72 bit double precision. I am not sure
about the CDC and Cray compilers. It isn't required that the *8
represent 8 bytes of any specific size. (The PDP-10 byte
instructions work on bytes from 1 to 36 bits. C compilers
tend to use 9 bits for char. C requires char to be an integer
fraction of the word (int) size.)


Thomas Koenig

unread,
Apr 10, 2022, 3:44:59 AM4/10/22
to
JCampbell <campbel...@gmail.com> schrieb:

> real(dp) or real(kind=dp) is not clear, as you need to search for the definition of dp, often in a "remote" module.
> sp, dp, qp, wp, r4 or r8 are not standard abbreviations. They are not uncommon real variables in legacy codes.

They are what I usually use. In most of my projects, I have a small
module

module prec
implicit none
integer, parameter :: sp = selected_real_kind(6)
integer, parameter :: dp = selected_real_kind(15)
integer, parameter :: qp = selected_real_kind(30)
end module prec

> I use multiple compilers, which have different kind values. Real*8 works easily for me on all compilers I use, while real(kind=dp) has the problem of which compiler last compiled the module where DP was defined.

Modules and object code are only valid for one compiler. If you
mix them, you're in for bigger trouble than that.

> One compiler has real_kinds of [ 1,2 ] and integer_kinds of [ 1,2,3,4 ]. Try using integers such as 123_4 and see what you get for the different compilers I use.

nagfor, I presume, although they have the -kind=byte option to
match what others are doing (market pressure, I presume).

I actually like the -kind=unique version best, no possiblity
of mixing up any of the kind numbers.

> When using real*8, there is always the danger of using a compiler
> that does not support this non-standard syntax. I think there
> are greater dangers out there at the moment! I have used new
> Fortran compilers that did not support the real*byte syntax. It
> has happened a few times and I always successfully lobbied for
> the compiler to be enhanced. Most new OS and compilers tend to
> want to help established users.

That is correct. I still find the difference between REAL*8
and COMPLEX*8 a source of confusion, though.

gah4

unread,
Apr 10, 2022, 3:46:34 AM4/10/22
to
On Saturday, April 9, 2022 at 9:46:13 AM UTC-7, Beliavsky wrote:
> On Saturday, April 9, 2022 at 12:16:46 PM UTC-4, gah4 wrote:
> > As far as I know, REAL(8) is more popular, and equally standard and
> > non-portable.

(snip)

> > REAL(KIND(1D0))

> > would be standard, and reliably give a double precision type, though takes
> > more characters to type.

> > It is nice to have something that can be replaced, line by line, without the
> > need for any other lines to be included. (Well, assuming appropriate
> > continuation rules.)

> If someone declares variables as real*8 they are saying that 8-byte reals are sufficient.
> You could have a platform where singe precision is real(kind=real64) and double
> precision is real(kind=real128). In that case the natural equivalent of real*8 would be
> real(kind=real128) and not real(kind=kind(1.0d0)).

The Cray-1 series are word addressed 64 bit machines, with a 64 bit
floating point type. I believe Fortran supports a software emulated 128
bit type, as required by the standard. But all the Cray machines are, as far
as I know, in museums. (There used to be a machine that would one on
one day a week, as that was how much power they could afford.)

I don't know about Cray support for REAL*8 syntax.

I do remember Fortran programs with a series of declarations and
DATA statements at the beginning, where you uncomment the ones
for the system you are using. That was for the different word size,
and also other constants that varied between machines.



Thomas Koenig

unread,
Apr 10, 2022, 3:59:28 AM4/10/22
to
gah4 <ga...@u.washington.edu> schrieb:
> On Saturday, April 9, 2022 at 2:29:37 PM UTC-7, Thomas Koenig wrote:
>> gah4 <ga...@u.washington.edu> schrieb:
>> > On Saturday, April 9, 2022 at 7:05:29 AM UTC-7, Beliavsky wrote:
>
> (snip)
>
>> > In the past, this was complicated by machines with 60 or 64 bit words,
>> > that had a type of that length as default REAL, and then (as required by
>> > the standard) a longer type of DOUBLE PRECISION. Those machines are
>> > now out of favor.
>
>> POWER has rather recently acquired IEEE quad precision, and
>> gfortran will have aquired support for it in the upcoming
>> release.
>
> It was the word addressed 60 and 64 bit machines that didn't have
> a smaller floating point type. IBM had REAL*16 and COMPLEX*32
> since the 360/85 and standard on all S/370 and later models.
>
> I am surprised it took this long to get to POWER.

IIRC, the REAL*16 types were implemented as two doubles. POWER also
had that (but as a pair of IEEE doubles), and a true headache it
is proving to get rid of that in compiler support.

> VAX Fortran also supports REAL*16 and COMPLEX*32, though
> software emulated on many machines. That was from close
> to the beginning of VAX. (A microcode option on most,
> it was standard on the low end 11/730.)

You will also find it as KIND=16 on gfortran, implemented
in software as well (libquadmath).

Dick Hendrickson

unread,
Apr 10, 2022, 12:01:18 PM4/10/22
to
On 4/10/22 2:46 AM, gah4 wrote:
> On Saturday, April 9, 2022 at 9:46:13 AM UTC-7, Beliavsky wrote:
>> On Saturday, April 9, 2022 at 12:16:46 PM UTC-4, gah4 wrote:
>>> As far as I know, REAL(8) is more popular, and equally standard and
>>> non-portable.
>
> (snip)
>
>>> REAL(KIND(1D0))
>
>>> would be standard, and reliably give a double precision type, though takes
>>> more characters to type.
>
>>> It is nice to have something that can be replaced, line by line, without the
>>> need for any other lines to be included. (Well, assuming appropriate
>>> continuation rules.)
>
>> If someone declares variables as real*8 they are saying that 8-byte reals are sufficient.
>> You could have a platform where singe precision is real(kind=real64) and double
>> precision is real(kind=real128). In that case the natural equivalent of real*8 would be
>> real(kind=real128) and not real(kind=kind(1.0d0)).
>
> The Cray-1 series are word addressed 64 bit machines, with a 64 bit
> floating point type. I believe Fortran supports a software emulated 128
> bit type, as required by the standard. But all the Cray machines are, as far
> as I know, in museums. (There used to be a machine that would one on
> one day a week, as that was how much power they could afford.)
>
> I don't know about Cray support for REAL*8 syntax.

Cray supported both real*4 and real*8 syntax. The syntax was easy, the
hard part was deciding what it meant. As you said, there was no
support for a 32 bit real; real*4 declared a 64 bit variable. The
hardware supported 64 bit real and software emulation did the 128 bit
real. The problem was most people used real*8 because 64 bits was
enough, not that they needed "double precision". Promoting real*8 to
twice the size of a real*4 wasn't what they wanted for performance.
Ultimately, we gave them a control card option to effectively treat
real*4 and real*8 as identical. Fortunately, the standard let us do that.

Dick Hendrickson

PS: there was one syntax issue. Things like REAL*4 HENRY initially
gave the parser fits.

gah4

unread,
Apr 10, 2022, 12:16:02 PM4/10/22
to
On Sunday, April 10, 2022 at 12:59:28 AM UTC-7, Thomas Koenig wrote:
> gah4 <ga...@u.washington.edu> schrieb:

(snip)

> > It was the word addressed 60 and 64 bit machines that didn't have
> > a smaller floating point type. IBM had REAL*16 and COMPLEX*32
> > since the 360/85 and standard on all S/370 and later models.
> >
> > I am surprised it took this long to get to POWER.

> IIRC, the REAL*16 types were implemented as two doubles. POWER also
> had that (but as a pair of IEEE doubles), and a true headache it
> is proving to get rid of that in compiler support.

The IBM HFP 16 byte type has the form of two of the usual 8 byte type.
Base 16 like the others, with a 7 bit exponent. That is the form that the
360/85 implemented, and was carried on through S/370 and ESA/390.

When IBM did it, they implemented DXR, extended precision divide,
only in software emulation. Statistics said that it wasn't used all that
much, such that it wasn't worth doing in hardware. The "two doubles"
format makes the software emulation a little easier, and 112 bits
is enough.

They also wrote the emulation software for other S/360 models,
again the format makes it easier. My first hand disassembly of
a whole program was those emulators. (After I figured out
how to extract hex dumps from load module libraries.
Sometime in high school years, if you are counting.)

Also, the 16 byte values are stored in a pair of floating
point registers. S/360 only has four such registers, so
only two pairs. Later, ESA/390 added more registers.

Also, late in the ESA/390 years, so maybe 1995 or so, they finally
added DXR to hardware. Maybe about the time that IEEE binary
floating point was added, including a 16 byte form.







Ron Shepard

unread,
Apr 10, 2022, 1:30:39 PM4/10/22
to
On 4/10/22 2:34 AM, gah4 wrote:
> Note, though, that the DEC compilers for the 36 bit PDP-10
> recognize REAL*8 for the 72 bit double precision. I am not sure
> about the CDC and Cray compilers. It isn't required that the *8
> represent 8 bytes of any specific size. (The PDP-10 byte
> instructions work on bytes from 1 to 36 bits. C compilers
> tend to use 9 bits for char. C requires char to be an integer
> fraction of the word (int) size.)

I remember using these machines in the late 1970s. My memory might be
off, but I remember being able to use REAL*4 (mapped to 36-bit single
precision) and REAL*8 (mapped to 72-bit double precision). This was
before the CHARACTER type was available, but Hollerith characters could
be stored in integer, real, double precision, or logical variables, or
even used in literal constants pretty freely. They were 7-bit ascii
characters, up to 5 per word (so one bit per word could be used by the
programmer for something else, if necessary). I never used an f77
compiler on those machines, but I think they did exist later on. I never
used C on those machines, so I do not know about its 9-bit characters,
but that would have been incompatible with both the fortran convention
and with all of the other uses of characters in the operating system
(file names, interactive shells, text editors, etc.).

I think gfortan even now has options that treat real*8 declarations as
single precision and real*16 as double precision. I don't use these, but
I think integer and logical kinds are all promoted too, so everything
works the way it should according to the standard storage sequence
requirements. There are, of course, incompatibilities with external
libraries such as BLAS and LAPACK that, in their naming convention,
continue to treat 4-byte integers and reals as single precision.

I also remember when CRAY started using byte-addressable CPUs (i.e. MIPS
and AMD chips). They tried to include options that would facilitate
porting from their earlier 64-bit word machines, but it was easy to make
mistakes with, for example, integer and real storage sequence
associations in common blocks.

$.02 -Ron Shepard

Ron Shepard

unread,
Apr 10, 2022, 1:48:14 PM4/10/22
to
On 4/10/22 2:44 AM, Thomas Koenig wrote:
>> real(dp) or real(kind=dp) is not clear, as you need to search for the definition of dp, often in a "remote" module.
>> sp, dp, qp, wp, r4 or r8 are not standard abbreviations. They are not uncommon real variables in legacy codes.
> They are what I usually use. In most of my projects, I have a small
> module
>
> module prec
> implicit none
> integer, parameter :: sp = selected_real_kind(6)
> integer, parameter :: dp = selected_real_kind(15)
> integer, parameter :: qp = selected_real_kind(30)
> end module prec

Just to include this possibility into the mix, there is also

real*8, private :: temp
integer, parameter :: wp=kind(temp)

The rest of the code should use the "wp" parameter of course, in
declarations and in literal constants, but in that one module, it isn't
so bad to use real*8 in that one place. Once it is localized like this,
it isn't even so bad to hardwire the kind number.

integer, parameter :: wp=8

The big porting problems arise when the "8" is scattered throughout the
source code.

$.02 -Ron Shepard

jfh

unread,
Apr 10, 2022, 6:43:39 PM4/10/22
to
On Sunday, April 10, 2022 at 7:44:59 PM UTC+12, Thomas Koenig wrote:
> JCampbell <campbel...@gmail.com> schrieb:
> > real(dp) or real(kind=dp) is not clear, as you need to search for the definition of dp, often in a "remote" module.
> > sp, dp, qp, wp, r4 or r8 are not standard abbreviations. They are not uncommon real variables in legacy codes.
> They are what I usually use. In most of my projects, I have a small
> module
>
> module prec
> implicit none
> integer, parameter :: sp = selected_real_kind(6)
> integer, parameter :: dp = selected_real_kind(15)
> integer, parameter :: qp = selected_real_kind(30)
> end module prec
> > I use multiple compilers, which have different kind values. Real*8 works easily for me on all compilers I use, while real(kind=dp) has the problem of which compiler last compiled the module where DP was defined.

In one of my projects where I test programs with lower precision to save run time but finish up using the highest I use a little module like this:

module myprec
integer, parameter :: prec(4) = [6,15,18,33]
integer, parameter :: wp = selected_real_kind(prec(2))
end module myprec

when I want what gfortran and ifort call double precision. Changing the desired precision requires changing only the 2 into 1, 3 or 4, and no change is needed in a program that uses that module.

That works well with gfortran but when compiling with ifort I must remember that asking for prec(3) is the same as asking for prec(4).

JCampbell

unread,
Apr 11, 2022, 12:38:38 AM4/11/22
to
I am not sure I would agree that real*10 works well with gfortran, especially considering the memory storage approach.
I do miss the precision of 8087 real*10, especially for loop accumulators, but the improved performance of real*8 SIMD : MMX, SSE and AVX is a must.
I have felt cheated by the alignment issues with SSE and AVX, which should have always been solved by the hardware and not left for programmers to try and fix with messy memory address calculations.
Rather than 8, 16 or 32 byte compiler alignment options for arrays, why is there not a 4096 byte (memory page) alignment, which "might" be useful for multi-threading for heap ALLOCATE arrays ?

Robin Vowels

unread,
Apr 11, 2022, 4:48:24 AM4/11/22
to
On Monday, April 11, 2022 at 3:48:14 AM UTC+10, Ron Shepard wrote:
> On 4/10/22 2:44 AM, Thomas Koenig wrote:
> >> real(dp) or real(kind=dp) is not clear, as you need to search for the definition of dp, often in a "remote" module.
> >> sp, dp, qp, wp, r4 or r8 are not standard abbreviations. They are not uncommon real variables in legacy codes.
> > They are what I usually use. In most of my projects, I have a small
> > module
> >
> > module prec
> > implicit none
> > integer, parameter :: sp = selected_real_kind(6)
> > integer, parameter :: dp = selected_real_kind(15)
> > integer, parameter :: qp = selected_real_kind(30)
> > end module prec
> Just to include this possibility into the mix, there is also
>
> real*8, private :: temp
.
It REALly isn't standard, is it !!
.

Robin Vowels

unread,
Apr 11, 2022, 5:00:25 AM4/11/22
to
.
In small test programs, REAL and DOUBLE PRECISION are clear,
and can be written quickly.

Robin Vowels

unread,
Apr 11, 2022, 5:03:04 AM4/11/22
to
.
Indeed !!!

Robin Vowels

unread,
Apr 11, 2022, 5:07:47 AM4/11/22
to
.
Can we not write in English? REAL (KIND=DP) :: x
.

Robin Vowels

unread,
Apr 11, 2022, 5:21:33 AM4/11/22
to
On Sunday, April 10, 2022 at 3:35:25 PM UTC+10, JCampbell wrote:
> On Sunday, April 10, 2022 at 12:05:29 AM UTC+10, Beliavsky wrote:
> > Since compilers treat the non-standard but very common
> >
> > real*4, real*8, integer*4, integer*8
> >
> > as
> >
> > use iso_fortran_env
> > real(kind=real32), real(kind=real64), integer(kind=int32), integer(kind=int64)
> >
> > would it make sense to standardize the former set of declarations, which is concise and clear, to mean the same as the latter?
> real*8 and real(kind=real64) both provide a clear documentation of precision.
> real(8) unfortunately, is not portable.
.
and real*8 is not standard.
>.
> real(dp) or real(kind=dp) is not clear,
.
in what way? "dp" is used often enough that it is immediately clear
that it signifies double precision.
.
>as you need to search for the definition of dp,
.
Really?
The purpose of using such "words" as 'dp' and 'wp' in your
programs makes it clear what the words mean.
.
> often in a "remote" module.
> sp, dp, qp, wp, r4 or r8 are not standard abbreviations. They are not uncommon real variables in legacy codes.
.
Can't say I have seen these in any old codes.
.
> I use multiple compilers, which have different kind values. Real*8 works easily for me on all compilers I use,
.
So does DOUBLE PRECISION, which is STANDARD.
.
> while real(kind=dp) has the problem of which compiler last compiled the module where DP was defined.
> One compiler has real_kinds of [ 1,2 ] and integer_kinds of [ 1,2,3,4 ]. Try using integers such as 123_4 and see what you get for the different compilers I use.
.
Don't use such silly suffixes.
.
> When using real*8, there is always the danger of using a compiler that does not support this non-standard syntax. I think there are greater dangers out there at the moment!
> I have used new Fortran compilers that did not support the real*byte syntax. It has happened a few times and I always successfully lobbied for the compiler to be enhanced.
.
"enhanced"? you mean, down-graded.
.
> Most new OS and compilers tend to want to help established users.
>
> IEEE documents also use REAL*8 syntax.
.
So what?

steve kargl

unread,
Apr 11, 2022, 12:05:49 PM4/11/22
to
JCampbell wrote:

> I am not sure I would agree that real*10 works well with gfortran, especially considering the memory storage approach.

Can you elaborate?

gfortran's real(10) on x86_64 class hardware is Intel 80-bit
extended double precision.

--
steve

Ron Shepard

unread,
Apr 11, 2022, 8:45:22 PM4/11/22
to
I think the problem people have is that it is stored in 16 bytes, so
there is a lot of wasted memory and/or file space.

I'm glad the option is there, for example for accumulating sums with
extended precision, but its overall usefulness is limited because of
those wasted 48-bits per value. Programmers instead are likely just to
use the 128-bit floating point kind which takes up the same memory/file
space. And it is nice to have the 128-bit kind supported too.

$.02 -Ron Shepard

steve kargl

unread,
Apr 12, 2022, 12:17:23 PM4/12/22
to
Then those people are blaming the wrong thing. Intel choose 4, 8, and 16-byte
alignment in their ABIs. gfortran (and gcc) are just a tool sitting above the cpu.

--
steve

John Collins

unread,
Apr 12, 2022, 2:04:21 PM4/12/22
to
On Monday, April 11, 2022 at 10:21:33 AM UTC+1, Robin Vowels wrote:
<snip>> .
> So does DOUBLE PRECISION, which is STANDARD.
> .

I'm not sure that it is, or at least, not in a helpful way. A system with a default 64-bit real number might interpret DOUBLE PRECISION as 128-bit.

I agree that standardising REAL*8 would inject a fossil into the language. Perhaps a way forward is to define a new class of PARAMETER for types and kinds, e.g.

PARAMETER,KIND :: REAL_8 = REAL,KIND=KIND(1.0D0)

Then REAL_8 could only be used in a kind specification and would always mean the same thing. This would avoid an error which we found recently in an important code where the user had written an expression of the form:

REAL(dp),PARAMETER :: kappa = 68431_dp

dp was (as a result of SELECTED_REAL_KIND) equal to 8 so the integer was defined as 64-bits and no error occurred on the original ifort compiler. What NAG or FTN95 would have done with it I don't want to know. We don't (yet) know how many more of these are likely to turn up. The compiler could issue an error if a parameterised KIND were used as a tag for an integer literal.

gah4

unread,
Apr 12, 2022, 2:23:32 PM4/12/22
to
On Tuesday, April 12, 2022 at 11:04:21 AM UTC-7, john.c...@simconglobal.com wrote:

(snip)

> I agree that standardising REAL*8 would inject a fossil into the language.
> Perhaps a way forward is to define a new class of PARAMETER for types and kinds, e.g.

> PARAMETER,KIND :: REAL_8 = REAL,KIND=KIND(1.0D0)

> Then REAL_8 could only be used in a kind specification and would always mean the same thing.
> This would avoid an error which we found recently in an important code where
> the user had written an expression of the form:

> REAL(dp),PARAMETER :: kappa = 68431_dp

The KIND values could have been required to be different for different
types, though they are required to be the same for a REAL type and the
twice as big COMPLEX type.

(IBM and DEC call the double precision complex type REAL*16.)

> dp was (as a result of SELECTED_REAL_KIND) equal to 8 so the integer
> was defined as 64-bits and no error occurred on the original ifort compiler.

> What NAG or FTN95 would have done with it I don't want to know.
> We don't (yet) know how many more of these are likely to turn up.
> The compiler could issue an error if a parameterised KIND were used as a tag for an integer literal.

As well as I know the standard, the KIND values are just integers.

The standard doesn't care much where you get your KIND values,
as long as the one you come up with is supported.

REAL(dp),PARAMETER :: kappa = 68431_dp

is legal, standard, but not portable.

I suspect one could claim that reusing KIND values between INTEGER and
REAL kinds is a quality of implementation issue, and that a high quality
implementation would not do that. Start sending in bug reports!

The original subject here is the non-standard REAL*8, but there is the
standard, non-portable, and way too common REAL(8).

There is no suggestion in the standard that REAL(8) exists,
and even less that it is an 8 byte or 64 bit type.



steve kargl

unread,
Apr 12, 2022, 3:52:47 PM4/12/22
to
John Collins wrote:

> On Monday, April 11, 2022 at 10:21:33 AM UTC+1, Robin Vowels wrote:
> <snip>> .
>> So does DOUBLE PRECISION, which is STANDARD.
>> .
>
> I'm not sure that it is, or at least, not in a helpful way. A system with a default 64-bit real number might interpret DOUBLE PRECISION as 128-bit.
>

DOUBLE PRECISION is defined by the standard. An entity with
default REAL kind type occupies one numeric storage unit.
An entity with DOUBLE PRECISION type occupies two numeric
storage units. If one numeric storage unit is 64 bits, then
two would use 128 bits.

--
steve

Phillip Helbig (undress to reply)

unread,
Apr 12, 2022, 4:06:28 PM4/12/22
to
In article <t34lac$utb$1...@dont-email.me>, steve kargl
Right. DOUBLE is really double the size, since the actual precision,
however it is measured, can vary, and is usually not double.

gah4

unread,
Apr 12, 2022, 4:40:37 PM4/12/22
to
On Tuesday, April 12, 2022 at 12:52:47 PM UTC-7, steve kargl wrote:

(snip)

> DOUBLE PRECISION is defined by the standard. An entity with
> default REAL kind type occupies one numeric storage unit.
> An entity with DOUBLE PRECISION type occupies two numeric
> storage units. If one numeric storage unit is 64 bits, then
> two would use 128 bits.

Yes, the word addressed Cray machines with 64 bit words, and CDC machines with 60 bit
words, did not have a smaller type. So the Fortran required double precision had to
be 128 bits, or 120 bits, respectively, and as well as I know, was done in software.

As far as I know, all those are in museums, so we don't have to plan for them.
Is there any thought that more such processor might be built?

Otherwise, for the IEEE 754 decimal forms, the basic (IEEE 754 term) forms
are the 64 bit and 128 bit forms. If there was interest in a Fortran compiler
supporting them as its default types, such that default REAL would be 64 bits,
then it would be useful, as above, to have a way to ask for this, without
asking for a double precision type.

Ron Shepard

unread,
Apr 13, 2022, 1:04:34 AM4/13/22
to
On 4/12/22 1:23 PM, gah4 wrote:
> The original subject here is the non-standard REAL*8, but there is the
> standard, non-portable, and way too common REAL(8).

There are thousands of lines of compiler documentation that use REAL(8)
because that is a concise way to describe how the compiler does things.
When new programmers see that documentation, they will mimic it in their
codes. This problem is not going away any time soon.

$.02 -Ron Shepard

Ron Shepard

unread,
Apr 13, 2022, 1:12:42 AM4/13/22
to
On 4/12/22 3:06 PM, Phillip Helbig (undress to reply) wrote:
[...]
> Right. DOUBLE is really double the size, since the actual precision,
> however it is measured, can vary, and is usually not double.

And sometimes the precision is more than double. Compare the 24-bit
mantissas in single precision to the 53-bit mantissas in double
precision. Those counts include the implicit hidden bit.

$.02 -Ron Shepard

Robin Vowels

unread,
Apr 13, 2022, 2:05:42 AM4/13/22
to
On Wednesday, April 13, 2022 at 4:04:21 AM UTC+10, john.c...@simconglobal.com wrote:
> On Monday, April 11, 2022 at 10:21:33 AM UTC+1, Robin Vowels wrote:
> <snip>> .
> > So does DOUBLE PRECISION, which is STANDARD.
> > .
> I'm not sure that it is, or at least, not in a helpful way. A system with a default 64-bit real number might interpret DOUBLE PRECISION as 128-bit.
.
How many of those do you use?
.
> I agree that standardising REAL*8 would inject a fossil into the language. Perhaps a way forward is to define a new class of PARAMETER for types and kinds, e.g.
>
> PARAMETER,KIND :: REAL_8 = REAL,KIND=KIND(1.0D0)
>
> Then REAL_8 could only be used in a kind specification and would always mean the same thing. This would avoid an error which we found recently in an important code where the user had written an expression of the form:
>
> REAL(dp),PARAMETER :: kappa = 68431_dp
>
> dp was (as a result of SELECTED_REAL_KIND) equal to 8 so the integer was defined as 64-bits and no error occurred on the original ifort compiler. What NAG or FTN95 would have done with it I don't want to know.
.
The design of the kind system in FORTRAN is flawed, and allows errors of this type to pass unnoticed.
The way around it is to have a kind number that is unique for every available kind.
Most manufacturers have circumvented this simple check and invented kind numbers
according to the number of bytes typically employed for the relevant real or integer.
Thus, compilers have the same kind number for both single-precision real [32-bit] and for
a default [32-bit] integer, and so on.
.
In PL/I we can write DECLARE X FLOAT DECIMAL(15);
and DECLARE Y FLOAT DECIMAL (6);
and get the precision that we desire, so that even if a machine
were available that offered only 64-bit reals, we would have
it using hardware floats of 64-bits for variables X and Y.
(Of course, the number of desired digits can be parameterised,
just as in Fortran, so that it would be easy to change.)
As well as the above, one can write DECLARE Z FLOAT BINARY (53);
if it is desired to express the requirement in binary digits.
..
>We don't (yet) know how many more of these are likely to turn up.
> The compiler could issue an error if a parameterised KIND were used as a tag for an integer literal.
.
It could do it now had the compiler writer used unique integers for every kind.
It doesn't need any language changes,.

Robin Vowels

unread,
Apr 13, 2022, 2:06:52 AM4/13/22
to
.
How many machines are using that offer only 64 bit reals?

Robin Vowels

unread,
Apr 13, 2022, 2:09:17 AM4/13/22
to
.
How long would it take to write a program to read in a Fortran
program and change REAL(8) to REAL(dp) ?

Robin Vowels

unread,
Apr 13, 2022, 2:13:05 AM4/13/22
to
On Wednesday, April 13, 2022 at 5:52:47 AM UTC+10, steve kargl wrote:
.
How many machines are you using that offer 64 bit words for single precision?

gah4

unread,
Apr 13, 2022, 3:44:14 AM4/13/22
to
On Tuesday, April 12, 2022 at 11:06:52 PM UTC-7, Robin Vowels wrote:

(snip)

> How many machines are using that offer only 64 bit reals?

Cray-1, Cray-1A, Cray-1S, Cray-1M, Cray-X-MP, Cray-Y-MP, Cray-2
Cray-C90 Cray-EL90.

How many of each did they make, so we can add them all up?

Robin Vowels

unread,
Apr 13, 2022, 4:24:03 AM4/13/22
to
On Wednesday, April 13, 2022 at 5:44:14 PM UTC+10, gah4 wrote:
> On Tuesday, April 12, 2022 at 11:06:52 PM UTC-7, Robin Vowels wrote:
>
> (snip)
> > How many machines are using that offer only 64 bit reals?
.
The word "you" was inadvertently omitted from the sentence.
.
> Cray-1, Cray-1A, Cray-1S, Cray-1M, Cray-X-MP, Cray-Y-MP, Cray-2
> Cray-C90 Cray-EL90.
>
> How many of each did they make, so we can add them all up?
.
There is none in use. Any that still exist are museum pieces.

Ron Shepard

unread,
Apr 13, 2022, 11:10:29 AM4/13/22
to
On 4/13/22 2:44 AM, gah4 wrote:
> On Tuesday, April 12, 2022 at 11:06:52 PM UTC-7, Robin Vowels wrote:
>
> (snip)
>
>> How many machines are using that offer only 64 bit reals?
>
> Cray-1, Cray-1A, Cray-1S, Cray-1M, Cray-X-MP, Cray-Y-MP, Cray-2
> Cray-C90 Cray-EL90.

I'm not sure exactly what this discussion is about, but fortran
compilers on those computers also supported 128-bit reals. Double
precision on those machines was slow, but it was there if you absolutely
needed it.

However, the FPS series of machines, which were also popular in the
1980s, did not support 128-bit arithmetic at all. They only supported
64-bit single precision floating point.

> How many of each did they make, so we can add them all up?

These were not personal computers, so the measure is not how many of the
computers were made, but rather how many programmers and users had
access to them. In my field of computational chemistry, that would be
essentially every active programmer. In the 1980s, one could gain access
in a variety of ways, through government agencies like NSF, NIH, DoD, or
DOE, through state computer access programs, through universities, or
through private employers. Those machines cast a huge shadow in their time.

$.02 -Ron Shepard

steve kargl

unread,
Apr 13, 2022, 11:46:39 AM4/13/22
to
I can run any code that I have with a 64-bit default real on x86_64 hardware.
The requirements in the Fortran standard do not place restrictions on the
underlying hardware.

% cat o.f90
program o
real a ! default real kind
real*4 b ! nonstanard, but portable, declaration
a = 0.1_4 ! initialization with kind type suffix
b = 3. ! default real kind literal real constant
print '(2I3,1X,G0)', storage_size(a), storage_size(b), a / b
a = exp(1.)
b = 4 * atan(1.)
print '(2I3,1X,G0)', storage_size(a), storage_size(b), a / b
end program

% gfortran11 -o z o.f90 && ./z
32 32 0.333333351E-1
32 32 0.865255952
% gfortran11 -o z o.f90 && ./z
% gfortran11 -o z -fdefault-real-8 o.f90 && ./z
64 32 0.33333333830038704E-1
64 32 0.86525595535432454
% gfortran11 -o z -freal-4-real-8 o.f90 && ./z
64 64 0.33333333333333333E-1
64 64 0.86525597943226507

I'll let you ponder what's going on.

--
steve


John Collins

unread,
Apr 13, 2022, 2:41:22 PM4/13/22
to
On Wednesday, April 13, 2022 at 7:09:17 AM UTC+1, Robin Vowels wrote:
> .
> How long would it take to write a program to read in a Fortran
> program and change REAL(8) to REAL(dp) ?

If the original code didn't have odd space characters, continuation lines and comments in silly places very little time at all. But I think that an issue here is that dp must be defined somewhere, and the definition added to every routine. Inserting an INCLUDE file or USE statement into every Fortran sub-program is much more work than a 1-line sed script.

We have done all this. But I think a simple, unambiguous declaration which didn't have any associated complexities would be useful. To that end REAL*8 is the best we have got, it works everywhere (at least that I know of) and doesn't need to be in the standard if everyone understands it.

gah4

unread,
Apr 13, 2022, 6:33:47 PM4/13/22
to
On Wednesday, April 13, 2022 at 8:10:29 AM UTC-7, Ron Shepard wrote:

(snip, I wrote)

> > Cray-1, Cray-1A, Cray-1S, Cray-1M, Cray-X-MP, Cray-Y-MP, Cray-2
> > Cray-C90 Cray-EL90.

> I'm not sure exactly what this discussion is about, but fortran
> compilers on those computers also supported 128-bit reals. Double
> precision on those machines was slow, but it was there if you absolutely
> needed it.

In the 1970's (mostly CDC) and 1980's (CDC and Cray), porting
programs was complicated if you wanted a 64 bit (more or less)
data type. That is, single precision on some machines, double
on others. (In addition, some other constants, sometimes many
other constants, would change between machines.)

One that I think I remember, from the card days, was cards for all
the different possibilities, each with a C in column 80. You then
reverse the card in the deck, so the C is in column 1, for those you
don't want to use.

In any case, REAL*8 suggests that you want about 64 bits,
and maybe about 53 bits of significand, on any machine.

It does not suggest that you want double precision on hardware
with a 60 or 64 bit single precision.

There are ways to do this within the standard, which take a lot
of typing, and also ways that are non-standard.

If you manage to USE the appropriate module, at the right time,
there is REAL64 and C_DOUBLE.

REAL(SELECTED_REAL_KIND(12))

might be about right, but is a lot to write. It is difficult to do a simple
string substitution without problems with continuations and such.

REAL(8) is shorter, but the standard does not give specific
KIND values, so one can't reliably expect any specific type,
or even that such type exists.

REAL*8 is easy to type, and does not suggest double precision on hardware
with a longer single precision type.


> However, the FPS series of machines, which were also popular in the
> 1980s, did not support 128-bit arithmetic at all. They only supported
> 64-bit single precision floating point.

Interesting. Since Fortran compilers were, as well as I know, not hosted
on the FPS machine, they might avoid the standard requirement for
a double precision type.

As well as I know it, C does not require or suggest that (double)
is twice the size, or otherwise more precision, than (float).
Systems with a 64 bit (float) can also have a 64 bit (double).



gah4

unread,
Apr 13, 2022, 8:38:12 PM4/13/22
to
On Wednesday, April 13, 2022 at 11:41:22 AM UTC-7, john.c...@simconglobal.com wrote:
> On Wednesday, April 13, 2022 at 7:09:17 AM UTC+1, Robin Vowels wrote:

> > How long would it take to write a program to read in a Fortran
> > program and change REAL(8) to REAL(dp) ?

> If the original code didn't have odd space characters, continuation lines
> and comments in silly places very little time at all.
> But I think that an issue here is that dp must be defined somewhere,
> and the defin