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

SELECTED_REAL_KIND can also present portability issues

559 views
Skip to first unread message

FortranFan

unread,
Apr 2, 2017, 9:16:08 AM4/2/17
to
Steve Lionel of Dr Fortran fame posted a blog (http://intel.ly/2nZSxoE) recently at the Intel software site on the KIND facilities in Fortran and he concluded, "Most applications should use the SELECTED_xxx_KIND intrinsics as I described..."

Dr Fortran blogpost was in reaction to suggestions made on this forum by some expert(s) on another recent thread which the 'doctor' didn't stop to examine fully, consequently found them objectionable, and he wrote, "we get to the point of contention I mentioned at the start of this post... Fortran 2008 extended intrinsic module ISO_FORTRAN_ENV to include named constants INT8, INT16, INT32, INT64, REAL32, REAL64 and REAL128 whose values correspond to the kinds of integer and real kinds that occupy the stated number of bits. More than one response in that newsgroup thread recommended using these instead of hard-coding integer and real kinds. In my view, this is little better than the old *n extension in that it tells you that a type fits in that many bits, but nothing else about it. As an example, there's one compiler where REAL128 is stored in 128 bits but is really the 80-bit "extended precision" real used in the old x86 floating point stack registers. If you use these you might think you're using a portable feature, but really you're not and may get bitten when the kind you get doesn't have the capabilities you need. My advice is to not use those constants unless you truly understand what they do and do not provide."

The blog thus raised a couple of alarms - quite loudly one might add - for beginning and casual or otherwise unsuspecting coders, but it did not offer any complete example or a traceable reference that illustrated how someone can actually "get bitten" or get themselves into "trouble down the road". Moreover, the blog did not present any additional insight into the nature or the probability or the frequency of the problem.

The main takeaways from the blog appeared to be that with REAL128 named constant "you might think you're using a portable feature, but really you're not and may get bitten " and that "Most applications should use the SELECTED_xxx_KIND intrinsics", the value of the recommendation to use SELECTED_REAL_KIND seems to be with portability, though it is not stated as such in the blog.

With this background, I would like to bring attention to Fortranners using a fully worked out example of a portability issue that can occur with SELECTED_REAL_KIND also. The example uses a simple computation explained in a paper by Ghazi et al., Computing in Science & Engineering, Volume 12, Issue 3, p5, May-June 2010 (ref*) in which they try "to determine 10 decimal digits
of the constant d = 173746a + 94228b − 78487c, where a = sin(1E22), b = log(17.1), and c = exp(0.42)."

[ref* http://ieeexplore.ieee.org/document/5457292/ ]

Note the quantities and the functions involved in the example computation present a challenge in terms of "double precision" arithmetic and a coder will quickly realize the need for extended precision, say something beyond the 15 that is offered by IEEE-754 binary64 floating-point type.

Now you can try to envision a scenario where a coder using Intel Fortran compiler determines a precision of 18 is good for the need at hand and writes code as shown below and calculates a result of d = -0.1341818958E-011 (rounded to 10 significant digits) which is the same as the expected value. The programmer can justifiably conclude the code is satisfactory, it appears standard-conforming, it seems to adhere to the advice of the good doctor at least re: portability with the use of SELECTED_REAL_KIND, and the processor agrees and it does not throw any warning or errors during compilation.

-- begin code --
program p
! see for reference: http://ieeexplore.ieee.org/document/5457292/

use, intrinsic :: iso_fortran_env, only : output_unit

implicit none

! Constants
integer, parameter :: wp = selected_real_kind( p=18 )
! Say a computational scientist guessetimates a precision of 18 is sufficient

! Calculation Constants
real(wp), parameter :: alpha = 1E22_wp
real(wp), parameter :: beta = 17.1_wp
real(wp), parameter :: gamma = 0.42_wp
real(wp), parameter :: c1 = 173746.0_wp
real(wp), parameter :: c2 = 94228.0_wp
real(wp), parameter :: c3 = 78487.0_wp
real(wp), parameter :: d_expected = -0.1341818958E-11_wp

! format strings
character(len=*), parameter :: fmt_gen = "(*(g0))"
character(len=*), parameter :: fmt_hex = "(g0,z0)"
character(len=*), parameter :: fmt_pct = "(g0,1pg16.4)"
character(len=*), parameter :: NL = new_line("")

! variables
real(wp) :: a
real(wp) :: b
real(wp) :: c
real(wp) :: d

!
write( output_unit, fmt=fmt_gen ) ProgTitle() // NL

a = sin( alpha )
b = log( beta )
c = exp( gamma )

! Computation
d = c1*a + c2*b - c3*c

! Output results
write( output_unit, fmt=fmt_gen ) "Results for working precision defined by " // &
"SELECTED_REAL_KIND( P=18 )" // NL
write( output_unit, fmt=fmt_gen ) "d = ", d
write( output_unit, fmt=fmt_hex ) "d in HEX: ", d
write( output_unit, fmt=fmt_pct ) "% error in d = ", (d/d_expected - 1.0_wp)*100.0_wp
write( output_unit, fmt=fmt_gen ) "d (expected) = ", d_expected
write( output_unit, fmt=fmt_hex ) "d (expected) in HEX: ", d_expected

stop

contains

function ProgTitle() result( Title )

!
integer :: i
integer, parameter :: Ititle(*) = &
[ 80,114,111,103,114,97,109,32,116,111,32,99,111,109,112,117,116,101,32,100,32,61, &
32,49,55,51,55,52,54,97,32,43,32,57,52,50,50,56,98,32,45,32,55,56,52,56,55,99,10, &
119,104,101,114,101,32,97,32,61,32,115,105,110,40,49,69,50,50,41,44,32,98,32,61, &
32,108,111,103,40,49,55,46,49,41,44,32,97,110,100,32,99,32,61,32,101,120,112,40, &
48,46,52,50,41,46,10,65,115,115,117,109,101,32,119,101,32,119,97,110,116,32,116, &
111,32,100,101,116,101,114,109,105,110,101,32,49,48,32,115,105,103,110,105,102, &
105,99,97,110,116,115,32,100,105,103,105,116,115,32,105,110,32,116,104,101,32,97, &
110,115,119,101,114,46,10,84,104,101,32,101,120,112,101,99,116,101,100,32,114, &
101,115,117,108,116,32,105,115,32,100,32,61,32,45,48,46,49,51,52,49,56,49,56,57, &
53,56,69,45,49,49 ]
! Function result
character(len=size(Ititle)) :: Title

forall (i=1:size(Ititle)) Title(i:i) = achar( Ititle(i) )

return

end function ProgTitle

end program p
-- end code --

Now say a need has been presented where the code needs to be ported to another compiler, say gfortran. Processing the code with gfortran will also show no warnings or errors and runtime execution will be without any exceptions. However, one will have to pay attention to notice the result using gfortran of d = -0.1314504061E-11 only provides an agreement of 4 significant digits with the expected value, compare this to 10 significant figures achieved with Intel Fortran.

Those familiar with gfortran will quickly realize the use of SELECTED_REAL_KIND with a precision of 18 matches the KIND result to the so-called KIND(10) which indeed has a precision of 18. But with Intel Fortran, the selected value is of KIND(16) with a precision of 33, for it is the only kind that can meet the minimum precision requested by the coder. It is the added precision in the chosen kind with the Intel Fortran case that allows the computed result to carry the extra accuracy in terms of significant digits in the result, but this can occur unbeknownst to the developer. A coder needs to be paying close attention to detail to notice such subtle differences, it is an aspect that indeed does get overlooked easily by many developers. Imagine now a situation where such a calculation is buried thousands of lines deep into a large, complex application and where the loss of 6 significant digits out of desired 10 in an intermediate result are impactful. It can consume countless hours of debugging exercise to uncover the problem. Of course a quick change involving only a couple of keystrokes in the SELECTED_REAL_KIND statement in the code to request a higher precision can resolve the matter, but that can only happen if the root cause can be so easily identified. I contend the situation shown here is similar to that alluded to in the above-mentioned blog with the use of the named constants from ISO_FORTRAN_ENV but here it is occurring with the touted cure, not the acursed disease in the blog.

So note in the particular example given here, if the coder had simply taken the 'shortcut' and made use of the named constant of REAL128 from ISO_FORTRAN_ENV intrinsic module, an approach that was the point of contention in the above-mentioned blog, it is highly likely the result would have been the same with both processors with d = -0.13418189578E-011 (full disclosure: this was only checked with a couple of different versions of Intel Fortran and gfortran compilers). Thus the portability exercise of going from Intel Fortran to gfortran would have been uneventful (as is desired during porting), at least for the computation at hand. This is because the computations would have obtained the few extra digits of precision required for accuracy in the calculations, regardless of how REAL128 is implemented by the processor and even if it were in a restricted manner with 80-bit 'extended precision'. Those who disagree with this are invited to provide some workable examples with sufficient detail, so readers can further their learning with precision and computations.

Note in computations that require precision beyond the so-called double precision, it's not often the number of digits of precision that can truly suffice for one's needs are known. Coders will then either pick the highest precision possible or resort to a newer paradigm involving "arbitrary precision", both of which only go in the direction of limiting the applicability of SELECTED_REAL_KIND option in end user code relative to the flexibility a coder might think there exists with precision and range selection.

I would then like readers to make a note of the following:

* recommendations come with qualifications and it is up to each "doctor" to explain the qualifications fully, for each reader to take the time and effort to notice and appreciate the qualifications an expert is striving to impart, often in a language different from one of their proficiency, and for each coder to develop a good understanding of them,

* while portability is a term bandied about a lot, one will struggle to find a fully detailed and workable definition of portability that can satisfy all the stakeholders of an application (particularly the pesky powers-that-be). Ultimately you may be responsible for defining it for your own needs, to determine the success factors for it, and how to validate your code against them.

* SELECTED_REAL_KIND is but one aspect that helps with portability, but even this can prove insufficient, as explained with the example above. Like with most things, paying attention of detail is critical to success, as can be seen here. Developing minimal working examples of crucial components of one's calculations and evaluating them thoroughly can make it easier to port code. More unit tests the better when it comes to validating code.

robin....@gmail.com

unread,
Apr 2, 2017, 11:15:50 AM4/2/17
to
Might there not be other factors at work here?
such as accuracy of built-in functions sin, log, exp,
but especially sin, as you are feeding it a rather large value, 1E22.

chinoun...@gmail.com

unread,
Apr 2, 2017, 12:18:31 PM4/2/17
to
That was the programmer mistake. Because he think that precision=18 is sufficient for his calculus, but he needs more precision than he think.
So the programmer must change the precision of his program to make it portable.
for example selected_real_kind(p=27)

mec...@gmail.com

unread,
Apr 2, 2017, 5:11:14 PM4/2/17
to
On Sunday, April 2, 2017 at 8:16:08 AM UTC-5, FortranFan wrote:
>
<---CUT--->
> * SELECTED_REAL_KIND is but one aspect that helps with portability, but even this can prove insufficient, as explained with the example above. Like with most things, paying attention of detail is critical to success, as can be seen here. Developing minimal working examples of crucial components of one's calculations and evaluating them thoroughly can make it easier to port code. More unit tests the better when it comes to validating code.

------------------

Your program is rather long and may induce some readers to skip reading it. Suppose you applied the same considerations to the following program:

---code---
print *,atan(1.0)-4*atan(0.2)+atan(1/239.0)
end
---end code---

What accuracy do you expect in the result, and how would you achieve, say, 7 digit accuracy in the result?

-- mecej4

FortranFan

unread,
Apr 2, 2017, 11:09:39 PM4/2/17
to
On Sunday, April 2, 2017 at 5:11:14 PM UTC-4, mec...@gmail.com wrote:

> ..
>
> Your program is rather long and may induce some readers to skip reading it. Suppose you applied the same considerations to the following program:
>

Thanks, that is a fair criticism. I understand and expect not just "some" readers but many will skip all or most of it for any number of other reasons, likely all attributable back to me somehow, well that's how things are. But it can be noticed readers skip too much even otherwise with the briefest and clearest of posts and then write things about them that are "flat out" inaccurate. To each their own then..

> ---code---
> print *,atan(1.0)-4*atan(0.2)+atan(1/239.0)
> end
> ---end code---
>
> What accuracy do you expect in the result, and how would you achieve, say, 7 digit accuracy in the result?
> ..

It'll be better to keep the focus on Fortran here and also on the aspects of portability, for that's all the blog referred to in the original post seems to address. Getting into numeric analysis can likely deflect this thread and invite a crowd to "wax eloquent" on the past but with little to no Fortran code, a scenario that is preferably avoided.

Please note my understanding is the simple computation described in the original post from the Ghazi et al. paper is reflective of a scenario where accumulation of different, unrelated, and disparate terms leave with an infinitesimal result that is still meaningful and whose computation is indeed dependent on precision. Modelers encounter this under any number of scenarios such as multiphysics simulations, economics, etc.

What you are bringing up is the residual of an identity whose result should be less than the EPSILON of the floating-point representation used for the numbers. i think it's a separate matter.

The point remains most users, definitely the beginning and casual coders, will find SELECTED_REAL_KIND a bit overwhelming and can plausibly get "bitten" by it too, as laid out in a scenario described in the original post.

Since an ounce of prevention can be worth a pound of cure, why not consider simplifying or clarifying the standard a bit for beginning and casual coders when it comes to REAL kinds and allow them to focus on computing aspects that are closer to their domain?

Stefano Zaghi

unread,
Apr 3, 2017, 5:21:01 AM4/3/17
to
Dear FortranFan,

Il giorno lunedì 3 aprile 2017 05:09:39 UTC+2, FortranFan ha scritto:
> Please note my understanding is the simple computation described in the original post from the Ghazi et al. paper is reflective of a scenario where accumulation of different, unrelated, and disparate terms leave with an infinitesimal result that is still meaningful and whose computation is indeed dependent on precision. Modelers encounter this under any number of scenarios such as multiphysics simulations, economics, etc.

Thank you very much for keeping the time to device such an interesting test, your help is really appreciated. However, I am quite surprise about the results: if 18 digits are enough, why the result of the GNU 80-bits representation is so different from the GNU 128-bits one? The possibilities are: 1) the 18 digits are, indeed, not enough, 2) the GNU 80-bits representation does not provide really 18 digits (or some issues are in the GNU Math library with 80-bits representation).

Anyhow, I think we can rarely say "a priori" which is the exact precision we need. More often, we can only "bound" our range, estimating that x-digits are or are not "roughly" enough. In this spirit, I had encoded your test with "selected_real_kind(15)" in the case I am sure that 64-bits representation of Intel and GNU are enough and "selected_real_kind(33)" if not.

The exploitation of the GNU 80-bits representation sounds like a "venture" choice: it is not really very "portable", meaning that, for example, Intel has not it, thus reverting back to the 128-bits representation. I understand that you have asked for a 18 digits representation, thus the GNU 80-bits representation looks like the smallest representation providing the requested precision (the best fitted, I could say), but this sounds "hazardous".

The portability issue you highlighted is very interesting, but I could suggest to separate the "bad results" of the GNU 80-bits representation, from the portability capability of "selected_real_kind": to me, you have asked 18 digits and "selected_real_kind" provided a good, portable, answer, namely 80-bits in GNU and 128 bits in Intel that has not the 80-bits representation. On the other side, it is not clear (for me) why the GNU 80-bits representation provides a so bad result, thus it could suggest that "selected_real_kind" can compromise the portability. Unluckily, I cannot test other compilers providing 80-bits representation for checking if the GNU 80-bits representation has some issues: it could be interesting if someone can provide such insights.

> The point remains most users, definitely the beginning and casual coders, will find SELECTED_REAL_KIND a bit overwhelming and can plausibly get "bitten" by it too, as laid out in a scenario described in the original post.

> Since an ounce of prevention can be worth a pound of cure, why not consider simplifying or clarifying the standard a bit for beginning and casual coders when it comes to REAL kinds and allow them to focus on computing aspects that are closer to their domain?

I totally agree, it could be very helpful a clarification or enhancement of the numbers kind definition.

My best regards.

David Duffy

unread,
Apr 3, 2017, 10:08:57 PM4/3/17
to
mec...@gmail.com wrote:
> print *,atan(1.0)-4*atan(0.2)+atan(1/239.0)
> end
>
> What accuracy do you expect in the result, and how would you achieve,
> say, 7 digit accuracy in the result?

use mpmodule
type (mp_real) :: res
write(*,*) '7 digits:'
call mpinit(7)
res=atan(mpreal(1))-4*atan(mpreal(1)/mpreal(5))+atan(mpreal(1)/mpreal(239))
mpoud=7 ! output digits
call mpwrite(6, res)
write(*,*) '2000 digits:'
call mpinit(2000)
res=atan(mpreal(1))-4*atan(mpreal(1)/mpreal(5))+atan(mpreal(1)/mpreal(239))
mpoud=7
call mpwrite(6, res)

7 digits:
10 ^ -11 x 7.8548892,
2000 digits:
10 ^ -2009 x -4.6176546,

:)


mecej4

unread,
Apr 4, 2017, 5:17:09 AM4/4/17
to
Thanks. It is interesting that the MP package is "erring on the safe
side". Tith mpoud=7, for example, 10 ^ -10 instead of the hinted 10 ^
-8. It is even more interesting that the first four digits (after
truncation, rather than rounding), match those of Pi/4!

Regards.

campbel...@gmail.com

unread,
Apr 7, 2017, 3:28:43 AM4/7/17
to
> integer, parameter :: wp = selected_real_kind( p=18 )

> ! Say a computational scientist guessetimates a precision of 18 is sufficient
>
> real(wp), parameter :: alpha = 1E22_wp
>
> a = sin( alpha )

"Say a computational scientist guessetimates a precision of 18 is sufficient" !!

What computational scientist would guessetimates p=18 for a = sin( 1E22_wp
) ??

This clearly illustrates my dislike of Selected_Real_Kind (p=18) as this computational scientist clearly does not know what he is doing. There is no understanding of the precision required for the SIN computation. In all likelihood, p=18 was chosen so that Selected_Real_Kind would give the hoped for KIND response.

You are taking the SIN of a number accurate to the nearest 10,000. What answer do you expect to get ? Is there any check of accuracy of the result.


steve kargl

unread,
Apr 7, 2017, 1:10:30 PM4/7/17
to
campbel...@gmail.com wrote:

>> integer, parameter :: wp = selected_real_kind( p=18 )
>
>> ! Say a computational scientist guessetimates a precision of 18 is sufficient
>>
>> real(wp), parameter :: alpha = 1E22_wp
>>
>> a = sin( alpha )
>
> "Say a computational scientist guessetimates a precision of 18 is sufficient" !!
>
> What computational scientist would guessetimates p=18 for a = sin( 1E22_wp
> ) ??

It's not a bad guess if one has some idea of his/hers computational facility.

> This clearly illustrates my dislike of Selected_Real_Kind (p=18) as this computational
> scientist clearly does not know what he is doing. There is no understanding of the
> precision required for the SIN computation. In all likelihood, p=18 was chosen so that
> Selected_Real_Kind would give the hoped for KIND response.
>
> You are taking the SIN of a number accurate to the nearest 10,000. What answer do
> you expect to get ? Is there any check of accuracy of the result.

Well, 1e22 is exactly representable in all floating pointing formats supported
by gfortran on X86_64 hardware. I get

sin(1e22_4) = -0.734082 0.47927 ULP
sin(1e22_8) = -0.734081535296102 0.12130 ULP
sin(1e22_10) = -0.734081535296101526 0.57595 ULP
sin(1e22_16) = -0.734081535296101539422863879735814

where the reference for the ULP computation is REAL(16).

OP's problem seems to be that he needs to read Goldberg's paper
a few times or the first chapter in Ralston and Rabinowitz. 18 decimal
digits of precision are clearly inadequate for the intermediate products
in his toy computation while it is perfectly adequate in representing the
final result.

--
steve


herrman...@gmail.com

unread,
Apr 7, 2017, 3:45:51 PM4/7/17
to
On Friday, April 7, 2017 at 10:10:30 AM UTC-7, steve kargl wrote:

(snip)

> OP's problem seems to be that he needs to read Goldberg's paper
> a few times or the first chapter in Ralston and Rabinowitz. 18 decimal
> digits of precision are clearly inadequate for the intermediate products
> in his toy computation while it is perfectly adequate in representing the
> final result.

Yes. For the majority of scientific computations, six digits
(single precision on many systems) is fine for the results.
For most algorithms, though, you need at least double precision
intermediate values to get single precision results.

But you still don't know if that is enough.

The IBM 7030 Stretch has an option to select whether 0's or 1's
are shifted in during post normalization. The idea is that you
do a calculation both ways, and compare the results. The biggest
problem I see is that, with the wrong luck, you subtract two such
values, and the difference cancels out.

As far as I know, this hasn't been done on any system since.

FortranFan

unread,
Apr 7, 2017, 3:47:30 PM4/7/17
to
On Friday, April 7, 2017 at 1:10:30 PM UTC-4, steve kargl wrote:

> ..
>
> ..
>
> OP's problem seems to be that he needs to read .. 18 decimal
> digits of precision are clearly inadequate for the intermediate products
> in his toy computation while it is perfectly adequate in representing the
> final result.
> ..

If one cares to read then they will notice I've been writing that coders are rarely, if at all ever, completely sure of their needs and requirements in floating-point precision, they may have arrive at a conclusion based on an incomplete picture and they may even be convinced they got it right because of their initial success but only realize much later (and possibly with a lot of grief) that wasn't the case. Few, if any, of actual problems being attempted by coders out there can be dissected as in the simple computation from the original post. Many coders including beginning and casual ones are thus at a disadvantage if they have to deal with SELECTED_REAL_KIND function.

As I have mentioned several times earlier, this is all about Fortran and the blog mentioned upthread, not numerical analysis alright?! In the blog, REALNN constants from ISO_FORTRAN_ENV are shown up for what they are, indicative of only the storage size; but then SELECTED_REAL_KIND is suggested but not fully dealt with in terms of its usage and implications. But now SELECTED_REAL_KIND function has precision, range, and radix as arguments which sounds all too well in the context of numerical analysis but there is a huge gap that develops when it comes to relating it to a given implementation (compiler X vs Y,e tc.). So it is only in connection with this that a wholly artificial, silly scenario dealing only with precision has been presented in the original post to show how it can trip up all but the most expert coders; there is nothing anywhere that says Fortran is only meant for them. Thus no one needs to wax eloquent on the numerical aspects here, the case was deliberately presented as such.

And get back to Fortran: if SELECTED_REAL_KIND( p=NN, range=MM ) can mean different precision in two different scenarios, it is just as problematic as all the noise presented in the blog with REALNN constants in ISO_FORTRAN_ENV. Those who care should be "verklempt": so here's a topic:

SELECTED_REAL_KIND is neither simple nor clear.

"Discuss":
https://en.wikipedia.org/wiki/Coffee_Talk#Discussion_topics
http://www.nbc.com/saturday-night-live/video/coffee-talk-cold-opening/2724263?snl=1

steve kargl

unread,
Apr 7, 2017, 4:45:27 PM4/7/17
to
FortranFan wrote:

>
> And get back to Fortran: if SELECTED_REAL_KIND( p=NN, range=MM ) can mean
> different precision in two different scenarios, it is just as problematic as all the
> noise presented in the blog with REALNN constants in ISO_FORTRAN_ENV. Those
> who care should be "verklempt": so here's a topic:
>

And therein lies the rub. You don't know what the Fortran Standard says. From
F2008: "The result [of SELECTED_REAL_KIND] has a value equal to a value of the
kind type parameter of a real type with decimal precision, as returned by the
function PRECISION, of at least P digits, ..."

"AT LEAST" does not mean the REAL type with the largest possible decimal
precision that exceeds the requested precision. It allows a processor to
use the REAL type with the smallest decimal precision that exceeds the
requested precision if two or more are available.

I'll note that both REALNN and SELECTED_REAL_KIND provide portability.
These just don't meet some conceived threshold on your part. If two
different processors on two entirely different systems provide a positive
value for REALNN, then you have a REAL type with NN bits of storage
on both. That's it. That's the portability that is required by the Fortran
standard. Likewise, if SELECTED_REAL_KIND(P=NN) returns a positive
value for the two fictitious processors on the two entirely different systems,
then you have a REAL type with AT LEAST NN decimal digits of precision.
That's it. That's the portability provided by the Fortran Standard.

How is a Fortran processor to know that a programmer who has requested
NN decimal digits of precision really wanted/needed/meant 2*NN decimal
digits of precision?

--
steve




FortranFan

unread,
Apr 7, 2017, 6:36:50 PM4/7/17
to
On Friday, April 7, 2017 at 4:45:27 PM UTC-4, steve kargl wrote:

> ..
>
> And therein lies the rub. You don't know what the Fortran Standard says. ..
>
> "AT LEAST" does not mean the REAL type with the largest possible decimal
> precision that exceeds the requested precision. ..
>
> I'll note that both REALNN and SELECTED_REAL_KIND provide portability.
> ..
>
> How is a Fortran processor to know that a programmer who has requested
> NN decimal digits of precision really wanted/needed/meant 2*NN decimal
> digits of precision?
> ..


It's the blog at http://intel.ly/2nZSxoE - NOT me - who is placing a high threshold on portability.

Note then my qualification that "SELECTED_REAL_KIND.. is just as problematic as .. REALNN constants in ISO_FORTRAN_ENV"


The point I am driving down toward is this: many, many coders, especially beginning and casual and also those in industry, can SIMPLIFY their lives by having option(s) in the Fortran standard that allow them to work quickly with IEEE Std 754â„¢-2008* description of binary64, binary128 (and binary32) floating-point format parameters (and perhaps the decimal equivalents of these).

To heck with having to deal with SELECTED_REAL_KIND and specify the precision, range, and radix.

Why can't the standard simply give such coders a quick, consistent, and clear option, say via the IEEE_ARITHMETIC intrinsic module where there are named constants that *precisely* match the format specifications of IEEE 754 2008 standard? Why can't they just do:

--
use IEEE_ARITHMETIC, only : WP => IEEE_BINARY64 ! Or IEEE_BINARY128, IEEE_BINARY32
..
real(WP) :: x
..
--

Currently, every programming group that I work with does its *own* thing and comes with its own solution (say their own KINDS module) that essentially strives to match the 3 floating-point formats specified in the IEEE 754 standard. It's a lot of needless effort for us and a real pain to ensure consistency and a lot of it get managed in questionable ways.

* https://standards.ieee.org/findstds/standard/754-2008.html




steve kargl

unread,
Apr 7, 2017, 7:11:28 PM4/7/17
to
FortranFan wrote:

> On Friday, April 7, 2017 at 4:45:27 PM UTC-4, steve kargl wrote:
>
>> ..
>>
>> And therein lies the rub. You don't know what the Fortran Standard says. ..
>>
>> "AT LEAST" does not mean the REAL type with the largest possible decimal
>> precision that exceeds the requested precision. ..
>>
>> I'll note that both REALNN and SELECTED_REAL_KIND provide portability.
>> ..
>>
>> How is a Fortran processor to know that a programmer who has requested
>> NN decimal digits of precision really wanted/needed/meant 2*NN decimal
>> digits of precision?
>> ..
>
>
> It's the blog at http://intel.ly/2nZSxoE - NOT me - who is placing a high threshold on portability.
>
> Note then my qualification that "SELECTED_REAL_KIND.. is just as problematic as .. REALNN constants in ISO_FORTRAN_ENV"
>
>
> The point I am driving down toward is this: many, many coders, especially beginning and casual and also those in industry, can SIMPLIFY their lives by having option(s) in the Fortran standard that allow them to work quickly with IEEE Std 754â„¢-2008* description of binary64, binary128 (and binary32) floating-point format parameters (and perhaps the decimal equivalents of these).
>
> To heck with having to deal with SELECTED_REAL_KIND and specify the precision, range, and radix.

Here is were I think your argument falls flat. If a programmer is knowledgeable enough to know
that she wants/needs IEEE 754 binary32 or binary64 or binary128 types, then that programmer
probably has sufficient knowledge to use SELECTED_REAL_KIND. That programmer has likely
actually check the model numbers, and written a MYTYPES modules.

> Why can't the standard simply give such coders a quick, consistent, and clear option,
> say via the IEEE_ARITHMETIC intrinsic module where there are named constants that
> *precisely* match the format specifications of IEEE 754 2008 standard?

You're not an old timer on USENET, are you? The double dash signals the start of a
user's signature. None of the reminder of your post was copied into my editor. :(

Do you really believe beginning and casual coders are going to understrand
the IEEE modules within the Fortran Standard, be sufficiently knowledge to
know that their calculation requires a minimum binary precision, and they
cannot figure out how to use SELECTED_REAL_KIND?

--
steve



Phillip Helbig (undress to reply)

unread,
Apr 7, 2017, 7:22:16 PM4/7/17
to
In article <5c26eeaa-8116-4445...@googlegroups.com>,
herrman...@gmail.com writes:

> Yes. For the majority of scientific computations, six digits
> (single precision on many systems) is fine for the results.
> For most algorithms, though, you need at least double precision
> intermediate values to get single precision results.

So, DOUBLE PRECISION library stuff, and REAL in the main program. :-)

campbel...@gmail.com

unread,
Apr 7, 2017, 11:01:12 PM4/7/17
to
On Saturday, April 8, 2017 at 8:36:50 AM UTC+10, FortranFan wrote:
>
> Why can't the standard simply give such coders a quick, consistent, and clear option, say via the IEEE_ARITHMETIC intrinsic module where there are named constants that *precisely* match the format specifications of IEEE 754 2008 standard? Why can't they just do:
>

There is a quick, consistent, and clear option : REAL*8
Even Kahan's paper Lecture Notes on the Status of IEEE Standard 754 for Binary Floating-Point Arithmetic uses this notation.

robin....@gmail.com

unread,
Apr 8, 2017, 4:47:20 AM4/8/17
to
On Saturday, April 8, 2017 at 1:01:12 PM UTC+10, campbel...@gmail.com wrote:
> On Saturday, April 8, 2017 at 8:36:50 AM UTC+10, FortranFan wrote:
> >
> > Why can't the standard simply give such coders a quick, consistent, and clear option, say via the IEEE_ARITHMETIC intrinsic module where there are named constants that *precisely* match the format specifications of IEEE 754 2008 standard? Why can't they just do:
>
> There is a quick, consistent, and clear option : REAL*8

Definitely not.
It is not standard.

> Even Kahan's paper Lecture Notes on the Status of IEEE Standard 754 for Binary Floating-Point Arithmetic uses this notation.

Just because someone uses a non-standard feature is NOT an endorsement of its
use.

Kind (1.0d0) is good for double precision, as well as other standard
alternatives.

Phillip Helbig (undress to reply)

unread,
Apr 8, 2017, 6:13:16 AM4/8/17
to
In article <7a4afc4e-9d0b-4234...@googlegroups.com>,
campbel...@gmail.com writes:

> On Saturday, April 8, 2017 at 8:36:50 AM UTC+10, FortranFan wrote:
> >
> > Why can't the standard simply give such coders a quick, consistent, and c=
> lear option, say via the IEEE_ARITHMETIC intrinsic module where there are n=
> amed constants that *precisely* match the format specifications of IEEE 754=
> 2008 standard? Why can't they just do:
>
> There is a quick, consistent, and clear option : REAL*8
> Even Kahan's paper Lecture Notes on the Status of IEEE Standard 754 for Bin=
> ary Floating-Point Arithmetic uses this notation.

It is not standard.

Phillip Helbig (undress to reply)

unread,
Apr 8, 2017, 6:14:59 AM4/8/17
to
In article <aed5ed2c-f502-469a...@googlegroups.com>,
robin....@gmail.com writes:

> Kind (1.0d0) is good for double precision, as well as other standard
> alternatives.

Is there ever ANY reason to use KIND(1.0D0) instead of DOUBLE PRECISION?
Yes, a variable can be used and declarations (and perhaps constants)
changed more easily, but if one needs DOUBLE PRECISION, then surely
there would be few, if any, cases where one would need to change this.

robin....@gmail.com

unread,
Apr 8, 2017, 9:43:08 AM4/8/17
to
On Saturday, April 8, 2017 at 8:14:59 PM UTC+10, Phillip Helbig (undress to reply) wrote:
> In article <aed5ed2c-f502-469a...@googlegroups.com>,
> r......@gmail.com writes:
>
> > Kind (1.0d0) is good for double precision, as well as other standard
> > alternatives.
>
> Is there ever ANY reason to use KIND(1.0D0) instead of DOUBLE PRECISION?
> Yes, a variable can be used and declarations (and perhaps constants)
> changed more easily, but if one needs DOUBLE PRECISION, then surely
> there would be few, if any, cases where one would need to change this.

For casual users, REAL and DOUBLE PRECISION are still good.

Richard Maine

unread,
Apr 8, 2017, 11:49:29 AM4/8/17
to
Phillip Helbig (undress to reply) <hel...@asclothestro.multivax.de>
wrote:

> Is there ever ANY reason to use KIND(1.0D0) instead of DOUBLE PRECISION?

The only place I could ever see it is in the declaration of a kind
parameter, something like

integer, parameter :: dp = kind(1.0d0)

--
Richard Maine
email: last name at domain . net
dimnain: summer-triangle

FortranFan

unread,
Apr 8, 2017, 11:32:17 PM4/8/17
to
On Saturday, April 8, 2017 at 6:14:59 AM UTC-4, Phillip Helbig (undress to reply) wrote:

> ..
>
> Is there ever ANY reason to use KIND(1.0D0) instead of DOUBLE PRECISION?
> ..


No one but you can be sure what you're trying to convey, but if you are making a case for the token "DOUBLE PRECISION" in code then it is backwards.

Fortran standard says, "The type specifier DOUBLE PRECISION specifies type real with double precision kind; the kind value is KIND (0.0D0)". This effectively implying 'DOUBLE PRECISION' is just a TYPEDEF (borrowing from C terminology) for 'REAL( KIND=KIND(0.0D0) )'.

Now if 'DOUBLE PRECISION' wasn't such an obfuscation with respect to the underlying floating-point representation and not such an abomination in terms of its bloated and jarring phraseology, one could tolerate it.

But no, it is in 'bad taste' in several ways. The use of 'DOUBLE PRECISION' needs to be discontinued, just as the <intrinsic type>*N syntax (e.g., REAL*8) needs to be confined to the dustbins of history.

FortranFan

unread,
Apr 8, 2017, 11:52:13 PM4/8/17
to
On Friday, April 7, 2017 at 7:11:28 PM UTC-4, steve kargl wrote:

> ..
>
> You're not an old timer on USENET, are you? ..

I only know Google Groups! What's USENET? Oops, I take back the question - I don't want to know and don't care any longer.

It was 'my bad' regardless, an oversight. I didn't mean to have the 'double dash space' sequence. I had an email client not too long ago (Outlook Express perhaps?) that too used this sequence as a delimiter for signature and I should have better than to include in my post. My apologies.

For those who were wondering about the rest of the post, here it is:
*******************
-- begin snippet --
use IEEE_ARITHMETIC, only : WP => IEEE_BINARY64 ! Or IEEE_BINARY128, IEEE_BINARY32
..
real(WP) :: x
..
-- end snippet --

Currently, every programming group that I work with does its *own* thing and comes with its own solution (say their own KINDS module) that essentially strives to match the 3 floating-point formats specified in the IEEE 754 standard. It's a lot of needless effort for us and a real pain to ensure consistency and a lot of it get managed in questionable ways.

* https://standards.ieee.org/findstds/standard/754-2008.html

*******************

jfh

unread,
Apr 9, 2017, 8:10:22 PM4/9/17
to
Because the standard allows 1d0, which is the same as 1.0d0, I would use REAL(KIND(1D0)) instead of DOUBLE PRECISION because I often want the same precision for a COMPLEX entity, and COMPLEX(KIND(1D0)) does that.
Neither DOUBLE COMPLEX nor DOUBLE PRECISION COMPLEX is in the Fortran standard.
But to save typing if there are a lot of real and complex entities to declare I might write
integer,parameter:: dp = kind(1d0)
real(dp) x
complex(dp) z
and as others have pointed out I need only change that integer,parameter line
to get a different precision, perhaps using selected_real_kind or real64. The standard does allow 1D0 as a shorter way to get 1.0D0.

Phillip Helbig (undress to reply)

unread,
Apr 10, 2017, 7:15:51 AM4/10/17
to
In article <a4a765c9-e3bd-41b7...@googlegroups.com>,
FortranFan <pare...@gmail.com> writes:

> > Is there ever ANY reason to use KIND(1.0D0) instead of DOUBLE PRECISION?
>
> No one but you can be sure what you're trying to convey, but if you are
> making a case for the token "DOUBLE PRECISION" in code then it is backwards.
>
> Fortran standard says, "The type specifier DOUBLE PRECISION specifies type
> real with double precision kind; the kind value is KIND (0.0D0)". This
> effectively implying 'DOUBLE PRECISION' is just a TYPEDEF (borrowing from C
> terminology) for 'REAL( KIND=KIND(0.0D0) )'.

In other words, DOUBLE PRECISION is a clearer way to say
REAL(KIND=KIND(0.0D0) ).

> Now if 'DOUBLE PRECISION' wasn't such an obfuscation with respect to the
> underlying floating-point representation

How is that different from REAL(KIND=KIND(0.0D0) )?

> and not such an abomination in terms
> of its bloated and jarring phraseology, one could tolerate it.
>
> But no, it is in 'bad taste' in several ways. The use of 'DOUBLE PRECISION
> ' needs to be discontinued, just as the <intrinsic type>*N syntax (e.g.,
> REAL*8) needs to be confined to the dustbins of history.

HUGE difference: the former has been standard for a long time and still
is, the latter has never been standard.

It's not even obsolescent, right?

FortranFan

unread,
Apr 10, 2017, 12:19:24 PM4/10/17
to
On Monday, April 10, 2017 at 7:15:51 AM UTC-4, Phillip Helbig wrote:

> ..
>
> In other words, DOUBLE PRECISION is a clearer way ..
>
> ..
>
> It's not even obsolescent, right?


DOUBLE PRECISION, as described by the Fortran standard, is not the same as what is commonly understood in terms of "double precision" by those who have any familiarity with computing. The two can be the same but the Fortran standard does not require it to be so. And that's the problem, especially in the context of this thread which refers to a blog that admonishes the use of REALNN constants in ISO_FORTRAN_ENV on account of their lack of specificity.

WG5 / J3 may never gain consensus to make 'DOUBLE PRECISION' obsolescent in the Fortran standard, I don't know.

But it is up to the user community to make its use deprecated in practice.

campbel...@gmail.com

unread,
Apr 10, 2017, 7:53:51 PM4/10/17
to
Which of the following conveys the more meaning ?
DOUBLE PRECISION,
REAL( KIND=KIND(0.0D0) ), or
REAL*8

I have a lot of experience porting Fortran code and I know which one of these statements I would prefer to read. It is often that the development operating system is not included in the documentation and without that, the first 2 options lack sufficient information.

Ron Shepard

unread,
Apr 10, 2017, 8:41:42 PM4/10/17
to
That is a little bit of a Hobsen's choice. The meanings of all three of
them depend on the compiler conventions, and possibly also the options
to the compiler when it is invoked.

I personally prefer to see

REAL(WP)

Because then I know that I can change the meaning of the WP parameter as
necessary for the compiler that I am using. If done correctly, that is
one line of code in an obvious location that might need to be changed,
and them I can compile thousands or millions of lines of code
consistently. With the three options you give, I might need to change
declarations all throughout the code to achieve that consistency.

$.02 -Ron Shepard

Stefano Zaghi

unread,
Apr 11, 2017, 12:00:25 AM4/11/17
to
Dear Campbel,

others (more experienced) have already given a reasonable answer to your question, but for the sake of clarity, hoping to help the new generation of Fortran programmers, I like to add also my answer.

The first choice, namely "double precision" does not convey a lot of meaning: I cannot say "a priori" which precision I will obtain neither which will be the actual memory requirements; it conveys only the notion to use "double" word memory that is not portable (each OS/Compiler could have different word length) and it does not specify the precision of the underling model. Moreover, it does not achieve real definition parametrization: as Ron said, to consistently change reals definition I have to change the whole program. Thus, I strongly suggest newbies to not use this kind of declaration.

The second choice, namely "real(kind=kind(1.d0))" is just a little better than the first one because it can be slightly modified in "integer, parameter :: wp = kind(1.d0) ; real(wp)" thus achieving definition parametrization. Similar considerations about precision/memory are still valid.

The last choice, namely "real*8" is the worst: it is not standard (sigh!), it is not portable (unknown meaning of precision/memory), it does not allow for definition parametrization.

As others, I think that "selected_real_kind" (or "iso_fortran_env" constants in suborder) is the best way to define reals in a sane approach, at least for the current standard. As FortranFan, I think there is space to improve the "wording" of the standard about "iso_fortran_env" constants and/or the kindness definition in general, but surely teaching newbies to use "real*8" is a bad one.

My best regards.

Wolfgang Kilian

unread,
Apr 11, 2017, 7:53:27 AM4/11/17
to
To answer the plain question directly, none of them, because all three
are meaningless without detailed knowledge about the hardware/OS/compiler.

Furthermore, all three are inconvenient for practical use.

DOUBLE PRECISION is standard, but since F90 it is an odd syntax given
that REAL(...) is available as a simpler replacement.

REAL (KIND=KIND(0.0D0)) is standard but even more odd for reading,
while using a named parameter for a compile-time constant is preferable
anyway.

REAL*8 is non-standard but short and likely to yield a real type with 8
bytes storage if you understand the notation -- except that the
compiler/hardware/OS has to agree with you, which you cannot enforce by
any means.

So, IMHO, the standard, short, and simple

REAL(<named-parameter>)

is an obvious choice. There is only the debate how to set
<named-parameter> in the first place. If you say that this is
system-dependent, I fully agree. You may take one of the
ISO_FORTRAN_ENV constants, because this guarantees storage (removing any
need for REAL*8), but it doesn't guarantee precision. But it's just one
line in the program which is system-dependent.

-- Wolfgang

--
E-mail: firstnameini...@domain.de
Domain: yahoo

Daniel Feenberg

unread,
Apr 11, 2017, 8:09:27 AM4/11/17
to
On Monday, April 10, 2017 at 7:53:51 PM UTC-4, campbel...@gmail.com wrote:
> Which of the following conveys the more meaning ?
> DOUBLE PRECISION,
> REAL( KIND=KIND(0.0D0) ), or
> REAL*8
>

Can anyone give an example of a Fortran processor that has different representations for the first two on the list? CDC 6000 doesn't count. I have a number of users at various sites. What effect can I expect on my users of switching from double to kind?

If the complaint is that "double" is arbitrary, what makes "0d0" anything else?

daniel feenberg

campbel...@gmail.com

unread,
Apr 11, 2017, 9:37:25 AM4/11/17
to
Daniel,

I don't know a current processor/compiler combination that would not support real*8. One advantage of supplying code with real*8 is that if the processor/compiler does not support 8-bit reals, then you would probably get an error report, although as real*8 is not defined in F90+ you can't be sure it would provide an error report.

It has been a long time since I used a processor that did not support real*8; CDC in 1977 or possibly ICL in 1981 ? Not really sure ?
I used an unknown IBM mainframe in about 1982, which gave new meaning to the Fortran Standard description "is processor dependent".
There are a few industry wide features that I still use that are not in the standard. However, to me, the real problem is how many features that are in the standard but are not clearly defined by the standard, being described as "processor dependent". These produce non-portable standard complying code.
These are time bombs in most Fortran code just waiting to go off. They typically appear when you are using a new operating system or environment with new restrictions, so it can be difficult to identify the problem. OPEN ( ..., RECL=rec_len,..), or the values of KIND are examples I have most recently experienced, but real*8 last failed for me nearly 40 years ago.

I wonder how many modern Fortran 2008 conforming codes would work first time if moved to another hardware/operating system/compiler combination ? Imagine the problems if it didn't support 8-byte reals. Think of all the data structure alignment issues you would get with sub-modules in that case !!

John

FortranFan

unread,
Apr 11, 2017, 9:47:35 AM4/11/17
to
On Tuesday, April 11, 2017 at 8:09:27 AM UTC-4, Daniel Feenberg wrote:

> ..
>
> Can anyone give an example of a Fortran processor that has different
> representations for the first two on the list? .. I have a number of users at
> various sites. What effect can I expect on my users of switching from double
> to kind? ..

@Daniel Feenberg,

It's best to figure it out for yourself!

If your users at the various sites are using a Fortran processor that conforms to Fortran 90 or a subsequent standard revision, have them run the following simple test and determine for themselves what the "first two" mean for them.

-- begin test code --
program p

implicit none

double precision :: foo
real(kind=kind(0D0)) :: bar

print *, "Properties of 'DOUBLE PRECISION :: foo':"
print *, " Precision = ", precision(foo)
print *, " Range = ", range(foo)
print *, " Radix = ", radix(foo)
print *, " Digits = ", digits(foo)
print *, "Min Exponent = ", minexponent(foo)
print *, "Max Exponent = ", maxexponent(foo)
print *, " Huge = ", huge(foo)
print *, " Tiny = ", tiny(foo)
print *, " PI = ", real(4.0,kind=kind(foo))*atan( real(1.0,kind=kind(foo)))

print *, "Properties of 'REAL(KIND=KIND(0D0)) :: bar':"
print *, " Precision = ", precision(bar)
print *, " Range = ", range(bar)
print *, " Radix = ", radix(bar)
print *, " Digits = ", digits(bar)
print *, "Min Exponent = ", minexponent(bar)
print *, "Max Exponent = ", maxexponent(bar)
print *, " Huge = ", huge(bar)
print *, " Tiny = ", tiny(bar)
print *, " PI = ", real(4.0,kind=kind(bar))*atan( real(1.0,kind=kind(bar)))

stop

end program p
-- end test code --

Upon execution of above using Intel Fortran on an Intel Core I3 running Windows 7 OS (64-bit), the output is:

-- begin output with Intel Fortran on Windows 7 64-bit OS --
Properties of 'DOUBLE PRECISION :: foo':
Precision = 15
Range = 307
Radix = 2
Digits = 53
Min Exponent = -1021
Max Exponent = 1024
Huge = 1.797693134862316E+308
Tiny = 2.225073858507201E-308
PI = 3.14159265358979

Properties of 'REAL(KIND=KIND(0D0)) :: bar':
Precision = 15
Range = 307
Radix = 2
Digits = 53
Min Exponent = -1021
Max Exponent = 1024
Huge = 1.797693134862316E+308
Tiny = 2.225073858507201E-308
PI = 3.14159265358979
-- end output --

Note it is only as expected with a standard-conforming processor that the two sets of properties (as shown above) are *identical* to each other. But the point is the above properties, while they will always be the same as each other, need NOT agree with what is commonly understood as 'double precision'. As to which processors and platforms will this be the case, I don't know - perhaps you will report back here using the above test!

As summarized nicely upthread by Stefano Zaghi, Wolfgang Kilian, and Ron Shephard, the recommendation is to define the floating-point (and other intrinsic in one place with named constants and employ such named constants in the code, see PENF and other work by Stefano Zaghi for great examples:
https://github.com/szaghi/PENF
https://github.com/Fortran-FOSS-Programmers/FOODIE

The point of this thread is captured perfectly by Wolfgang Kilian in his statement, "There is only the debate how to set <named-parameter> in the first place .. this is system-dependent .. But it's just one line in the program which is system-dependent"

And another point I'm making is that in our industry there is a conscious decision to perform all the computing with floating-point arithmetic defined per IEEE 754 2008 standard:

**********
So the Fortran standard can help us out by introducing a few more <named-parameter> in the IEEE_ARITHMETIC intrinsic module e.g., IEEE_BINARY32, IEEE_BINARY64, IEEE_BINARY128 (and perhaps IEEE_DECIMALNN too!) which will indicate REAL KINDs that are *precisely* consistent with IEEE 754 2008 standard (or will have some negative values if the processor does not support them).
**********

This is so that we can stay away from this debate altogether, once and for all (hopefully)! We will then do the needful to ensure the best use of such new <named-parameter>s in our code and to educate and evangelize their use with the coders.

See a couple of Wikipedia pages for further background:
https://en.wikipedia.org/wiki/Double-precision_floating-point_format
https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format


Richard Maine

unread,
Apr 11, 2017, 10:46:21 AM4/11/17
to
Daniel Feenberg <feen...@gmail.com> wrote:

> On Monday, April 10, 2017 at 7:53:51 PM UTC-4, campbel...@gmail.com wrote:
> > Which of the following conveys the more meaning ?
> > DOUBLE PRECISION,
> > REAL( KIND=KIND(0.0D0) ), or
> > REAL*8
> >
>
> Can anyone give an example of a Fortran processor that has different
> representations for the first two on the list? CDC 6000 doesn't count.

I'm not entirely sure what you mean. There are *ZERO* processors that
would give different representations for the first 2 above. the
kind=(0.0d0) *MEANS* to use the same kind as double; the procesor
doesn't have any option in that. If anyone finds such a processor, it
would just plain be broken.

Your mention of CDC makes me think that you might be asking a different
question, perhaps whether there are any processors where the first two
are different from real*8. The answer to that is yes. There are
processors where sngle precision real is 64 bits and double is 128 bits.
Note that in standard-speak, "processor" means the whole combination of
compiler, linker, whatever else is needed, and hardware. There are
compilers for quite mundane PC hardware that have 64-bit singles.

I'm not going to bother participating in a continuing debate about using
the real*8 syntax. I don't use it myself, would never recommend it to
anyone else, and have used multiple systems where it would not be
accepted at all. There are also environments where management rules
would not allow such a nonstandard usage. I will say nothing more about
that.

Let me repeat that nowhere have I *EVER* seen actual code using the
real(kind=(0.0d0)) syntax. I think that would be a horrible thing to do.
The only place I have seen that is in short examples in textbooks or
other places giving examples (like usenet posts). I wish peopel wouldn't
use it even in examples, because others then think those examples are
realistic. The appropriate comparison is real(kind=wp) or real(wp),
where wp is a named constant (and you are free to choose a different
name).

--
Richard Maine
email: last name at domain . net
domain: summer-triangle

FortranFan

unread,
Apr 11, 2017, 11:08:30 AM4/11/17
to
On Tuesday, April 11, 2017 at 10:46:21 AM UTC-4, Richard Maine wrote:

> ..
>
> Let me repeat that nowhere have I *EVER* seen actual code using the
> real(kind=(0.0d0)) syntax. I think that would be a horrible thing to do.
> The only place I have seen that is in short examples in textbooks or
> other places giving examples (like usenet posts). I wish peopel wouldn't
> use it even in examples, because others then think those examples are
> realistic. ..


Great advice! Add to this list the abomination with the use of literal KIND values such as 8, 10, etc. as in the to-be-avoided "REAL(KIND=8)".

The "moral police" on this forum should first haul up those who indulge in such "offences", particularly as they are often committed by those who are rather long in the tooth, which then make it more probable for the flock to be led down the wrong path!! :-)))

FortranFan

unread,
Apr 11, 2017, 11:49:20 AM4/11/17
to
On Tuesday, April 11, 2017 at 9:37:25 AM UTC-4, campbel...@gmail.com wrote:

> .. if the processor/compiler does not support 8-bit reals, ..
> These are time bombs in most Fortran code just waiting to go off. ..
>
> I wonder how many modern Fortran 2008 conforming codes would work first time if moved to another hardware/operating system/compiler combination ? ..


To all other readers, especially those who are not neck-deep into Fortran-related matters and this forum,

Please remember "correlation does not imply causation." This poster has often been conflating things and indulging in all manner of logical fallacies, but is now getting into sheer speculation as well as needless fear-mongering.

If you are taken aback by the comment about "time bombs in most Fortran code", ask that poster to either furnish a complete, workable example (that will accepted as such by at least a couple of Fortran experts) or "forever hold the peace"!

Also, note there is no evidence based on which you need to be concerned about any *intrinsic* portability issues with "modern Fortran" codes: there is a steadily increasing body of FOSS initiatives making use of "modern Fortran" that one can study in cyberspace e.g., at GitHub.

Take a look for yourself and see how many wonderful FOSS developers are making "modern Fortran" codes available which work on various Linux distros in addition to Windows OS and IBM AIX, etc. and where developers successfully cross-check and validate their code with as many different Fortran compilers as they can manage.

If you have any issues with using "modern Fortran" codes or porting them to multiple platforms, post on this forum or StackOverflow or Intel Fortran forums and you shall be served well - it's almost a guarantee!

robin....@gmail.com

unread,
Apr 11, 2017, 9:55:51 PM4/11/17
to
On Tuesday, April 11, 2017 at 11:37:25 PM UTC+10, campbel...@gmail.com wrote:

> I don't know a current processor/compiler combination that would not support
> real*8. One advantage of supplying code with real*8 is that if the
> processor/compiler does not support 8-bit reals,

8-bit reals? real-ly truly?

> then you would probably get an error report,

As would be the case with any incorrect statement.

> although as real*8 is not defined in F90+ you can't be sure it would provide an error report.

It would if you ask for strict standard compliance.

> It has been a long time since I used a processor that did not support real*8;
> CDC in 1977 or possibly ICL in 1981 ? Not really sure ?
> I used an unknown IBM mainframe in about 1982, which gave new meaning to the
> Fortran Standard description "is processor dependent".
> There are a few industry wide features that I still use that are not in the
> standard.

Time bombs waiting to go off !

> However, to me, the real problem is how many features that are in the
> standard but are not clearly defined by the standard, being described
> as "processor dependent". These produce non-portable standard complying code.
> These are time bombs in most Fortran code just waiting to go off.
> They typically appear when you are using a new operating system or
> environment with new restrictions, so it can be difficult to identify the
> problem. OPEN ( ..., RECL=rec_len,..), or the values of KIND are examples
> I have most recently experienced,

If you got failures with KIND values, you are not using them correctly.

> but real*8 last failed for me nearly 40 years ago.

When did DOUBLE PRECISION last fail? Was it 1957?

> I wonder how many modern Fortran 2008 conforming codes would work first time if moved to another hardware/operating system/compiler combination ? Imagine the problems if it didn't support 8-byte reals.

If it didn't, you'd only have yourself to blame.

campbel...@gmail.com

unread,
Apr 14, 2017, 10:23:50 PM4/14/17
to
My comment about "Time bombs waiting to go off" was in relation to the use of "processor dependent" in the standard. This allows for variable response in different compiler/hardware combinations.
Your response "Please remember "correlation does not imply causation." This poster has often been conflating things and indulging in all manner of logical fallacies, but is now getting into sheer speculation as well as needless fear-mongering." should be seen as your logical fallacy. Am I not allowed to highlight problems in the standard ?

I consider the use of "processor dependent" to be a significant problem for portability, which is often not recognised. I am disappointed that few appear to agree.

herrman...@gmail.com

unread,
Apr 15, 2017, 12:35:25 AM4/15/17
to
On Friday, April 14, 2017 at 7:23:50 PM UTC-7, campbel...@gmail.com wrote:

(snip)

> My comment about "Time bombs waiting to go off" was in relation
> to the use of "processor dependent" in the standard.

> This allows for variable response in different compiler/hardware
> combinations.

Well, much of floating point is processor dependent.

Note for comparison that Java requires IEEE floating point,
such that float and double are IEEE binary 32 bit, and 64 bit,
respectively.

There is a rumor (no idea if it is true) that IBM added IEEE
floating point to ESA/390 to support Java.

But Fortran has, over the years, allowed for many different
floating point systems, and that isn't likely to change.

robin....@gmail.com

unread,
Apr 15, 2017, 5:23:03 AM4/15/17
to
On Saturday, April 15, 2017 at 12:23:50 PM UTC+10, campbel...@gmail.com wrote:
> My comment about "Time bombs waiting to go off" was in relation to the use of "processor dependent" in the standard. This allows for variable response in different compiler/hardware combinations.
> Your response "Please remember "correlation does not imply causation." This poster has often been conflating things and indulging in all manner of logical fallacies, but is now getting into sheer speculation as well as needless fear-mongering." should be seen as your logical fallacy. Am I not allowed to highlight problems in the standard ?
>
> I consider the use of "processor dependent" to be a significant problem for portability, which is often not recognised. I am disappointed that few appear to agree.

Much computing is processor-dependent.

Other things that are processor dependent include the method of representing
negative numbers, the order in which float arithmetic operations are carried
out, optimisation, and so on.

Gary Scott

unread,
Apr 15, 2017, 11:29:23 AM4/15/17
to
I think that is widely understood, however the vast majority of software
involves operating system specific APIs for GUIs and many rely on
hardware specific APIs for add on IO cards. For pure
mathematical/algorithmic code, by all means obsess for portability
purposes. Otherwise, it may be a losing prospect.

dpb

unread,
Apr 15, 2017, 1:40:39 PM4/15/17
to
On 04/14/2017 9:23 PM, campbel...@gmail.com wrote:
...

> I consider the use of "processor dependent" to be a significant
> problem for portability, which is often not recognized. I am
> disappointed that few appear to agree.

I think what is recognized by most here is that it is inevitable unless
the Standard were to be written for a specific processor; it isn't
possible for the language to proscribe everything around it to produce
only absolutely identical results.

At that point it doesn't really matter much, either; it would be what
the one system did similar to the situation before was a Standard where
the fairly common assumption was that whatever the given vendor's
compiler did on the hardware on which it ran was "standard".

--


FortranFan

unread,
Apr 15, 2017, 1:45:56 PM4/15/17
to
On Friday, April 14, 2017 at 10:23:50 PM UTC-4, campbel...@gmail.com wrote:

> ..
>
> My comment about "Time bombs waiting to go off" was in relation to the use of "processor dependent" in the standard. This allows for variable response in different compiler/hardware combinations.
> .. Am I not allowed to highlight problems in the standard ?
>

> I consider the use of "processor dependent" to be a significant problem for portability, which is often not recognised. I am disappointed that few appear to agree.


@John Campbell,

Reader do NOT understand what are these "problem"s. Readers know there can be differences in floating-point arithmetic, character encoding, file systems, etc. on one platform versus another but also that there has been a lot of convergence in many aspects with efforts such as IEEE 754.

Re: "processor dependent" and say with the case you brought up of record length (RECL) while working with files:

-- copied text --------
Fortran standard states, "If the file is being connected for formatted input/output, the length is the number of characters for all records that contain only characters of default kind. When a record contains any nondefault characters, the effect of the RECL= specifier is processor dependent."
-- end text --------

So in this instance, what's the *problem* again? If one needs to work with files containing records containg characters that are not the default kind supported by the processor, one has to take some steps to meet those needs and the steps may vary from processor to processor, so what?

And if one has to do interact with OS-specific APIs or user-interface toolkits, one may need processor-specific directives, see below for an example with calling mechanism on Windows OS for an API to fetch the name of the executing module. Such matters have been deemed to be external to the Fortran standard and many will agree with the approach. So again, what's the big deal?

-- begin code snippet --
interface
function GetModuleFileName ..
..
#ifdef _WIN32
#ifdef __GFORTRAN__
!GCC$ ATTRIBUTES STDCALL :: GetModuleFileName
#elif __INTEL_COMPILER
!DIR$ ATTRIBUTES STDCALL :: GetModuleFileName
#endif
#endif
end function GetModuleFileName
..
-- end code snippet --

In the absence of any useful explanation or any suitable illustration on your part to accompany your words and little evidence on display of even any effort to put together any examples to help others understand what could be the problems and under what circumstances, your comments come closest to the "boy who cried wolf".

You say, "I have a lot of experience porting Fortran code". Then I challenge you to put together a generic minimal workable example from your experience of a situation involving "Time bombs waiting to go off".

As I have done on this forum before with a paraphrase of the Lord Kelvin quote, with others who convey a lot of experience but do not provide anything concrete for readers (especially younger recent entrants to Fortran) to learn from:

".. when one can illustrate what one is commenting about, and express it in minimal working examples, one knows something about it; but when one cannot explain it, when one cannot express it in actual Fortran code snippets, one's knowledge is of a meagre and unsatisfactory kind; it may be the beginning of knowledge, but one has scarcely in one's thoughts advanced to the state of Scientific and Technical programmer, whatever the case may be."

(http://www.goodreads.com/quotes/166961-when-you-can-measure-what-you-are-speaking-about-and)

0 new messages