Code Comments
Programming Forum and web based access to our favorite programming groups.Hi, Right now i always use double precision :: a in my FORTRAN 90 codes. But I am not sure if this is same as real(8) :: a in FORTRAN 90. I am planning to switch from double precision :: a to integer, parameter :: WP=8 real(kind=WP) :: a I am curious to know what experienced FORTRAN 90 programmers prefer and why? Thanks in advance --Ari
Post Follow-up to this message"Arindam Chakraborty" <arimail77@yahoo.com> wrote in message news:4f273f02.0408240942.3cfd4b4@posting.google.com... > I am planning to switch from > double precision :: a > to > integer, parameter :: WP=8 > real(kind=WP) :: a > Well, using an explicit constant 8 could get you into trouble in the long term, if your code is intended to be long lived and highly portable. Why not try integer, parameter :: sp = kind(1.0) integer, parameter :: wp = selected_real_kind(2*precision(1.0_sp)) and you'll always get what you seem to intend? Regards, Mike Metcalf
Post Follow-up to this messageArindam Chakraborty wrote: > Hi, > Right now i always use > double precision :: a > in my FORTRAN 90 codes. > > But I am not sure if this is same as > real(8) :: a > in FORTRAN 90. > > > I am planning to switch from > double precision :: a > to > integer, parameter :: WP=8 > real(kind=WP) :: a > > I am curious to know what experienced FORTRAN 90 > programmers prefer and why? I do something like this: INTEGER, PARAMETER, PUBLIC :: Double = SELECTED_REAL_KIND(15) REAL( Double ) :: a because literal kind values are not portable. That is, a kind value of 8 may be equivalent to double precision with one compiler, but not with another. If you use the SELECTED_REAL_KIND intrinsics, you can be assured of always getting a double preicsion kind type. I use about 6 different compilers/platforms and I have no idea wh at the actual kind type values are on all of them. cheers, paulv p.s. I dunno if I qualify as an experienced Fortran90 programmer though. :o)
Post Follow-up to this messagearimail77@yahoo.com (Arindam Chakraborty) writes: > Right now i always use > double precision :: a > in my FORTRAN 90 codes. > > But I am not sure if this is same as > real(8) :: a > in FORTRAN 90. It is compiler-dependent whether 8 is a valid kind number for reals at all. On some compilers, a kind of 8 will mean the same thing as your double precision. On others, it won't be a valid kind at all and will fail compilation. On some it might mean the same thing as single precision, or mean some other precision. > I am planning to switch from > double precision :: a > to > integer, parameter :: WP=8 > real(kind=WP) :: a > > I am curious to know what experienced FORTRAN 90 > programmers prefer and why? Well, that's an improvement, but I'd go farther. The reason that is an improvement is that, assuming you put the definition of WP in a module (or an include file will also do), it becomes a one-line change if you want to convert everything to some other precision...or if you need to use a different kind number on different machines. You might have to use a different number, but at least it is easy to do so. With the "double precision" spelled out, it is considerably more work to do such a change. On some compilers, you won't want double precision, because single precision is already 64-bits for them. Using double precision in that case will be a 128-bit real, which will just make everything bigger and slower. The KIND mechanism lets you use the same syntax to select a 64-bit real, regardless of whether that happens to be single or double. The step that I'd go farther is to use the selected_real_kind intrinsic instead of the hard-wited value 8. If you do something more like integer, parameter :: WP = selected_real_kind(12,30) then you will get excellent portability. That will give you a real that has at least 12 decimal digits of precision and a range of at least 10**(-30) to 10**30. Adjust as might be appropriate for the application. Anyway, this will generally get you a 64-bit real. You don't have to worry about whether that is single or double precision or about what the particular kind number for it is; this will work with *ALL* f90 compilers that support a real at least that big (which is all f90 compilers that exist now or are ever likely to). -- Richard Maine | Good judgment comes from experience; email: my first.last at org.domain | experience comes from bad judgment. org: nasa, domain: gov | -- Mark Twain
Post Follow-up to this messageArindam Chakraborty wrote: > Hi, > Right now i always use > double precision :: a > in my FORTRAN 90 codes. > > But I am not sure if this is same as > real(8) :: a > in FORTRAN 90. > > > I am planning to switch from > double precision :: a > to > integer, parameter :: WP=8 > real(kind=WP) :: a > > I am curious to know what experienced FORTRAN 90 > programmers prefer and why? I wouldn't call myself very experienced, but I use a module where I store needed precisions, described using the "selected_*_kind" intrinsics. IIRC the magic numbers of kind constants like the one you specify above are not specified by the standard although most compilers seem to use the number of bytes, thus producing compatible results. module prec implicit none ! At least IEEE 754 double precision integer, parameter :: dp = selected_real_kind(15, 307) ! quad precision, fall back on double if quad is not available integer, parameter :: qp_preferred = selected_real_kind(30,1000) integer, parameter :: qp = (1+sign(1,qp_preferred))/2*qp_preferred+ & (1-sign(1,qp_preferred))/2*dp end module prec The quad precision thingy is something I've never used, but I found it so neat that I lifted it from this newsgroup just in case I would ever need it. Then in my code I do something like program foo use prec implicit none real(dp) :: bar ! etc. end program foo -- Janne Blomqvist
Post Follow-up to this messageArindam Chakraborty wrote: > Hi, > Right now i always use > double precision :: a > in my FORTRAN 90 codes. > > But I am not sure if this is same as > real(8) :: a > in FORTRAN 90. Well, REAL(8) is not standard in that the standard says nothing about what numbers mean what precision. There are probably implementations where REAL(1) is single and REAL(2) is double precision - and REAL(8) is an error. (Indeed, that's probably the way I would implement a compiler.) > I am planning to switch from > double precision :: a > to > integer, parameter :: WP=8 > real(kind=WP) :: a If you are going to set a parameter (and, presumably you'll really set it for the whole probram and put it in a module), why not use an inquiry function and get rid of the implementation dependent number? You could write: integer, parameter :: WP = KIND(0.0d0) This would set WP to the KIND of double precision no matter wat specific number a given implementation chose for that purpose. Once you are using WP everywhere, you could change the precision of you whole code (asside from KIND-less literals) with a change of WP. This would have the advantage that when you switch to a computer with higher default precision, you may no longer need double and might get faster code with single. You could make that selection (semi-) automatic: integer, parameter :: WP = SELECTED_REAL_KIND(10) This gives you the hardware KIND that carries precision at least similar to or exceeding 10 decimal digits. So, on a PC it would select double precision, and on the old Cray, it would select single. There is a move afoot to try to get an inquiry function that allows more precise selections of KIND based on bits rather than decimal digits. That's not standard yet though. -- J. Giles "I conclude that there are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies." -- C. A. R. Hoare
Post Follow-up to this messageJanne Blomqvist wrote: > I wouldn't call myself very experienced, but I use a module where I > store needed precisions, described using the "selected_*_kind" > intrinsics. IIRC the magic numbers of kind constants like the one you > specify above are not specified by the standard although most > compilers seem to use the number of bytes, thus producing compatible > results. > > module prec > > implicit none > > ! At least IEEE 754 double precision > integer, parameter :: dp = selected_real_kind(15, 307) > > ! quad precision, fall back on double if quad is not available > integer, parameter :: qp_preferred = selected_real_kind(30,1000) > integer, parameter :: qp = (1+sign(1,qp_preferred))/2*qp_preferred+ & > (1-sign(1,qp_preferred))/2*dp > > end module prec I do exactly the same thing (thanks to James van Buskirk's suggestion). Just a note though; the above parameter initialisation for "qp" will not work with the P GI f90 or f95 compiler -- at least for their current release, v5.2-1. The next release, v5 .2-2 (due any day now), supposedly has the problem fixed. I've used the PGI f90 compiler s ince v 3.something (2?) and the above qp initialisation has never worked. Every oth er f90/95 compiler I've used ate it up, no worries. > The quad precision thingy is something I've never used, but I found it > so neat that I lifted it from this newsgroup just in case I would ever > need it. I have needed quad precision to test some stuff on the supercomputah here. A nd it was so ridiculously easy to change the precision of every single floating point var iable in my code (changing one number in my Type_Kinds.f90 module and recompiling) that I don't know how people got by without the kind type specification system in the past! :o ) On the minus side, using quad increased my run times by a factor of 20! Yoicks. cheers, paulv
Post Follow-up to this messagePaul Van Delst wrote: > Arindam Chakraborty wrote: > > > > I do something like this: > > INTEGER, PARAMETER, PUBLIC :: Double = SELECTED_REAL_KIND(15) > REAL( Double ) :: a > > because literal kind values are not portable. That is, a kind value of 8 > may be equivalent to double precision with one compiler, but not with > another. If you use the SELECTED_REAL_KIND intrinsics, you can be > assured of always getting a double preicsion kind type. I use about 6 > different compilers/platforms and I have no idea what the actual kind > type values are on all of them. I disagree, on 64-bit platforms SELECTED_REAL_KIND(15) can plausibly return you the kind parameter of default reals. Perhaps you are confusing the notion of "double precision" and "64-bit real". The former concept is well defined by the Fortran standard, as a real taking up twice the storage of the default real (and presumably offering greater precision and range). The latter concept, however, appears nowhere in the standard. If you *did* mean a "64-bit real", then SELECTED_REAL_KIND(15) is *probably* the correct way to go. However, if you meant "double precision", then your code should instead look like this: INTEGER, PARAMETER, PUBLIC :: Double = KIND(0.0D0) REAL( Double ) :: a cheers, Rich -- Dr Richard H D Townsend Bartol Research Institute University of Delaware [ Delete VOID for valid email address ]
Post Follow-up to this messageGordon Sande wrote: ... > Is there anything to prevent a (lousy unknown) standard conforming > implementation from providing a bit more, but not double, precision as > measured by the PRECISION intrinsic? One could picture devoting more of > the second storeage location to exponent and less of it to mantissa to > provide a "double precision" with an extra large exponent range but less > than double the arithmetic precision. There's nothing necessarily "lousy" about it. If so, then IEEE double extended would have to be considered "lousy" since it provides more precision and exponent range than double, but less than quad. A precision intermediate between single and double is specified by the IEEE standard: single-extended. A 64-bit representation of that could be defined with the properties you describe (all the specifications for single-extended are given as inequalities like the precision must be greater than or equal to 32 bits and the exponent field must be greater than or equal to 11 bits). Would that necessarily be "lousy", especially if it were as fast as double? -- J. Giles "I conclude that there are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies." -- C. A. R. Hoare
Post Follow-up to this messageRich Townsend wrote: > Paul Van Delst wrote: > > > > I disagree, on 64-bit platforms SELECTED_REAL_KIND(15) can plausibly > return you the kind parameter of default reals. Perhaps you are > confusing the notion of "double precision" and "64-bit real". The former > concept is well defined by the Fortran standard, as a real taking up > twice the storage of the default real (and presumably offering greater > precision and range). The latter concept, however, appears nowhere in > the standard. Hello, What I want is a floating point kind type that has a precision of ~15 sig fi gs. I also do, INTEGER, PARAMETER, PUBLIC :: Single = SELECTED_REAL_KIND(6) to get a floating point kind type with a precision of ~6 sig figs. I also as sume that the storage space for my "Double" kind type is twice that of my "Single". I do a ssociate specific byte sizes for these kinds based on experience only, not the Fortra n standard. Any time I need to know the bit/byte sizes in code, I check them and compare them with my assumptions -- also stored in my Type_Kinds.f90 module like so: ! -- Expected 8-bit byte sizes of the floating point kinds INTEGER, PARAMETER, PUBLIC :: n_Bytes_Single = 4 INTEGER, PARAMETER, PUBLIC :: n_Bytes_Double = 8 INTEGER, PARAMETER, PUBLIC :: n_Bytes_Quad = 16 If the system I'm on doesn't agree with what I've defined in my code, I toss out an error message and stop. If I'm on a system where SELECTED_REAL_KIND(6) and SELECTED_REAL_KIND(15) gi ve me the same kind type, well, I don't know what I'd do. I think I'd consider the compiler busted. cheers, paulv
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.