Hello everyone,
I need some help to implement quad precision in gfortran. I have noticed in some discussions that the questions can sometimes be underspecified. If more info is needed, just let me know. I am running an Intel 12th gen Core i9 processor with 64 Gigs of RAM. I installed gfortran and checked to make certain that I have the libquadmath file. I found it in the lib subfolder of the gcc folder. A copy of some source code and results I used to test my precision follows in the uploaded jpeg. To test for various precision levels I changed the “16” to both 8 and 32 and reran the program and produced the following results, none of which produced any expected (by me) results:
Clearly I need help. I think my problem is related to syntax, but like most newcomers to fortran, I have experienced information overload. Suggestions please! Thanks.
program test
! use iso_fortran_env, wp => real32 ! single
!use iso_fortran_env, wp => real64 ! double
use iso_fortran_env, wp => real128 ! quad
implicit none
real(wp),parameter :: pi = acos(-1.0_wp)
real(wp) :: bq,cq,dq
bq = pi**0.5_wp
cq = pi**0.5_wp
dq = bq*cq
print *, pi
print *, dq
end program test
use these iso_fortran_env constants to avoid confusion.
define the wp parameter and use it everywhere you define a real number (e.g., don’t use 1.234, use 1.234_wp. 1.234 is a single precision number, no matter what variable to assign it).
if you need \pi, use acos(-1.0_wp) rather than trying to write it out.
#ifdef REAL32
integer,parameter,public :: wp = real32 !! real kind used by this module [4 bytes]
#elif REAL64
integer,parameter,public :: wp = real64 !! real kind used by this module [8 bytes]
#elif REAL128
integer,parameter,public :: wp = real128 !! real kind used by this module [16 bytes]
#else
integer,parameter,public :: wp = real64 !! real kind used by this module [8 bytes]
#endif
so, then you can use the compiler directive to define the real precision like so: gfortran test.f90 -cpp -D REAL128. Since this is using the preprocessor, you would normally use the .F90 file extension.
That was sweet! Thank you. I noticed that you used acos and not acosq as listed in the writeup for libquadmath found in “The GCC Quad-Precision Math LIbrary” on the net. So, I have to believe that I would use, say, exp rather than expq, or cosh rather than coshq.
Jacob, this really helps. I started with punched cards and FORTRAN IV in the '70s. As a working stiff I migrated away to VBA. Modern fortran is great, but vast. If there is one website that is your favorite for new info, what would it be? Thanks, Gary
Also, I would suggest that you use in parallel the Compiler Explorer platform as it will enable you to test quite fast ideas, and also see the results from different compilers/versions like in this example play around with compiler flags, etc.
Most definitely the Fortran website https://fortran-lang.org/ (browse the documentation there) and this Discourse for discussion. You can help us improve it by providing feedback or even submit improvements.
Nope. Not a peep from me on that topic. Strange thing though. My editor would not take a close command for a sequential file. It kept treating it like a comment line. Ran the code anyway. Output was just fine. Makes one wonder - what is acually required?
You write, “I started with punched cards and FORTRAN IV in the '70s… Modern fortran is great, …”
glad you like modern Fortran.
The quip with @jacobwilliams was based on the fact in Fortran a literal floating-point constant such as 0.5 is of default REAL type toward which the standard does not mandate a decimal precision but recommends it be at least 6. Most processors (see it as compilers) treat default REAL as what is colloquially called single-precision. This has been surprising to some newcomers to modern Fortran, hence that comment.
TL;DR: with modern Fortran, consider always a defined KIND for floating-point types and also a _k suffix with literal constants of floating point types for sure, but as needed with integer constants also.
You specified aq = 3.14159... and .5 as single precision. You need _p16 e.g. .5_p16 to enforce quad precision. And I would also recommend
aq=4*atan(1._p16)
bq=sqrt(aq)
etc. The aq change saves having to check that all the digits are correct, and the bq change is because quad precision sqrt runs faster and may be more accurate than the log and exp that **.5_p16 would require.
Thanks all for the help folks. So glad I switched from VBA. Wasn’t getting anywhere. Current fortran
code now runs with jaw-dropping precision that I would never have thought possible as a kid.
Not too slow either.
You may know you can continue with VBA, especially when it comes to use with Microsoft Excel spreadsheet environment which, in a way (e.g., # of users), remains the world’s largest simulator with quite a few influential people using it as a primary compute platform for some of their monumental errors!
You can then package your modern Fortran code for consumption via VBA in Excel - see here for a trivial example that may kindle what you already know. You can then have the best of both worlds as long as you remain mindful it can be the worst of both if one is not careful!