From: Simon Geard on 18 Jan 2010 08:46 What is the best way to define mathematical constants for use in Fortran? For example I could define module Constants real(8), parameter :: E = 2.718281828459045d0 ! e real(8), parameter :: PI = 3.141592653589793d0 ! pi end module Constants but there are other possibilities. Is there a recommended standard/best practice? Is there a 'constants' module in the 2008 spec? Thanks, Simon
From: Arjen Markus on 18 Jan 2010 09:17 On 18 jan, 14:46, Simon Geard <si...(a)whiteowl.co.uk> wrote: > What is the best way to define mathematical constants for use in > Fortran? For example I could define > > module Constants > real(8), parameter :: E = 2.718281828459045d0 ! e > real(8), parameter :: PI = 3.141592653589793d0 ! pi > end module Constants > > but there are other possibilities. Is there a recommended standard/best > practice? Is there a 'constants' module in the 2008 spec? > > Thanks, > > Simon I'd say that the above is the most reliable way to define them. You could use transcendental functions like exp() and atan() to get mathematically sane expressions for at least these two constants, but you will run into trouble with cross-compiling (the compiler would have to emulate the transcendental functions of the target platform) and the standard does not necessarily allow all such functions in such an initialisation expression (if I understand it correctly, precisely for that reason). More importantly perhaps, the results of your program might depend on the quality of the library routines that you would be using. Using literal constants (especially in double precision and enough digits) is the most robust way to achieve what you want. Regards, Arjen PS I will be happy to add such a module to my flibs project :).
From: James Van Buskirk on 18 Jan 2010 11:29 "Arjen Markus" <arjen.markus895(a)gmail.com> wrote in message news:c1758405-8d2f-4709-95ab-b9e4967e3236(a)21g2000yqj.googlegroups.com... On 18 jan, 14:46, Simon Geard <si...(a)whiteowl.co.uk> wrote: > > What is the best way to define mathematical constants for use in > > Fortran? For example I could define > > module Constants > > real(8), parameter :: E = 2.718281828459045d0 ! e > > real(8), parameter :: PI = 3.141592653589793d0 ! pi > > end module Constants > > but there are other possibilities. Is there a recommended standard/best > > practice? Is there a 'constants' module in the 2008 spec? > I'd say that the above is the most reliable way to define them. > You could use transcendental functions like exp() and atan() to get > mathematically sane expressions for at least these two constants, > but you will run into trouble with cross-compiling (the compiler > would have to emulate the transcendental functions of the target > platform) and the standard does not necessarily allow all such > functions in such an initialisation expression (if I understand > it correctly, precisely for that reason). Actually, f03 makes initialization expressions much more of a free- fire zone. In f95 there was a separate class of constant expressions which lacked self-consistency and required the vendor to provide 4 effective compilers (one for ordinary expressions, one for specification expressions, one for initialization expressions, and one for constant expressions) but the first corregendum to f95 eliminated consant expressions by editing out their effects throughout the standard. Later, an f95 constant expression was made to be an f03 initialization expression, and transcendental functions and transformational functions became fair game at this point. There were some rough edges involved in these changes and in fact as a result you can write code that should behave differently under the f95 and f03 standards, but the differences are esoteric enough that I don't think any compiler actually catches them when the f95 standard is enforced. gfortran is the most agile cross compiler out there and it does use a gpl software package to compute initialization expressions. For it at least the initialization expression results are often more accurate than the ordinary expression results: C:\gfortran\clf\accurate_init>type accurate_init.f90 module funcs implicit none integer, parameter :: dp = selected_real_kind(15,300) contains subroutine sub(x) real(dp) x real(dp) y y = cos(cmplx(atan(real(1,kind(x))),x,kind(x))) write(*,*) y end subroutine sub end module funcs program accurate_init use funcs implicit none real(dp), parameter :: x = & cos(cmplx(atan(real(1,kind(x))),log(huge(x))+1,kind(x))) real(dp) y write(*,*) x y = log(huge(x))+1 call sub(y) end program accurate_init C:\gfortran\clf\accurate_init>gfortran accurate_init.f90 -oaccurate_init C:\gfortran\clf\accurate_init>accurate_init 1.72768693203654562E+308 +Infinity This is one where it's tricky to avoid overflow and the initialization expression package is powerful enough (and maybe slow enough) to get the right result. -- write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, & 6.0134700243160014d-154/),(/'x'/)); end
From: robert.corbett on 19 Jan 2010 03:50 On Jan 18, 6:17 am, Arjen Markus <arjen.markus...(a)gmail.com> wrote: > More importantly perhaps, the results of your program might > depend on the quality of the library routines that you would > be using. I would like to second this. Although there are many compilers that have trouble converting floating-point constants to internal values with complete accuracy, your odds are much better with literal constants than with transcendental functions. Bob Corbett
From: Paul Hirose on 19 Jan 2010 14:14
"Simon Geard" <simon(a)whiteowl.co.uk> wrote in message news:hj1oo1$5k2$1(a)news.eternal-september.org... > What is the best way to define mathematical constants for use in > Fortran? For example I could define > > module Constants > real(8), parameter :: E = 2.718281828459045d0 ! e > real(8), parameter :: PI = 3.141592653589793d0 ! pi > end module Constants I calculate constants like those at run time. That way, someone maintaining the code doesn't have to wonder where I got the values, whether they contain a typo, etc. Nowadays even a budget Windows machine does floating point in hardware per the IEEE standard, so I believe arc cosine of -1 is a safe way to compute pi, for example. However, I'd be interested to hear of any cases where this would have caused trouble. Sometimes the representation of a type is not specified by the language. It's up to the implementer. With these languages, computing math constants at runtime automatically upgrades their accuracy if, say, "double precision" someday changes to a 128 bit representation. Simply recompile your old code under the new architecture. -- Paul Hirose <jvcmz89uwf(a)earINVALIDthlink.net> To reply by email remove INVALID |