I'm looking over some examples from Ramsden & Lin's "Fortran 90 conversion course for F77 programmers", and glancing over the chapter which shows KIND parameter. I've never used it before, sticking to old DOUBLE PRECISION when it was needed.
One of the simplest examples was this:
INTEGER, PARAMETER :: idp = KIND(1.0D) REAL(KIND=idp) :: ra
WRITE(*,*)KIND(ra) END
onto which cvf66c and ifort gave an error, reporting syntax error in the first line (INTEG .... 1.0D)
Also, the mentioned compilers do not seem to support KIND=2 type. Is there something I'm doing wrong, or is the mentioned book just written for some other compiler?
On May 8, 11:52 am, Luka Djigas <ldigas@@gmail.com> wrote:
> INTEGER, PARAMETER :: idp = KIND(1.0D)
This should be INTEGER, PARAMETER :: idp = KIND(1.0D0) ^^^ notice that you're missing the exponent for the number.
> Also, the mentioned compilers do not seem to support KIND=2 type. Is > there something I'm doing wrong, or is the mentioned book just written > for some other compiler?
The value of KIND is internal representation of the compiler. It's not necessarily portable, so different compiler may have different value of KIND to represent the same precision. i.e the result of : WRITE(*,*)KIND(ra) may be different for different compiler.
So the way to select the KIND is by doing what you have in the example, or using function such as selected_int_kind() or selected_real_kind().
Luka Djigas wrote: > I'm looking over some examples from Ramsden & Lin's "Fortran 90 > conversion course for F77 programmers", and glancing over the chapter > which shows KIND parameter. I've never used it before, sticking to old > DOUBLE PRECISION when it was needed.
> onto which cvf66c and ifort gave an error, reporting syntax error in > the first line (INTEG .... 1.0D)
> Also, the mentioned compilers do not seem to support KIND=2 type. Is > there something I'm doing wrong, or is the mentioned book just written > for some other compiler?
> with regards, > Luka
Unless I'm missing something, the first line looks OK. Could you show the actual results? Are you sure you aren't compiling in fixed form mode rather than free form?
There is no particular standard meaning for KIND=2, it certainly isn't guaranteed to be double precision. Most processors now use kind numbers that are related to bytes; 4 for single, 8 for double. But, that isn't required.
The purpose of the KIND system is to allow you to specify what you need or want for the precision of floating point variables. Specifying KIND(1.0D0) is just another way of spelling DOUBLE PRECISION. You're usually better off to use the SELECTED_REAL_KIND intrinsic and specify something like
and then you're guaranteed to get 13+ digits of precision on all processors. Specifying DOUBLE PRECISION (or KIND(1.0D0)) is likely to get you 26 digits of precision on a machine whose native floating point mode is 64 or 128 bits rather than the more common 32/62 bits. That's likely to be noticeably slower.
On Fri, 8 May 2009 09:37:47 -0700 (PDT), reubendb <reube...@gmail.com> wrote:
>Hello,
>On May 8, 11:52 am, Luka Djigas <ldigas@@gmail.com> wrote:
>> INTEGER, PARAMETER :: idp = KIND(1.0D)
>This should be >INTEGER, PARAMETER :: idp = KIND(1.0D0) > ^^^ >notice that you're missing the exponent for the number.
Ah, I see. Must've been a mistype in the book.
>> Also, the mentioned compilers do not seem to support KIND=2 type. Is >> there something I'm doing wrong, or is the mentioned book just written >> for some other compiler?
>The value of KIND is internal representation of the compiler. It's not >necessarily portable, so different compiler may have different value >of KIND to represent the same precision. i.e the result of : >WRITE(*,*)KIND(ra) >may be different for different compiler.
>So the way to select the KIND is by doing what you have in the >example, or using function such as selected_int_kind() or >selected_real_kind().
So, if I wish to achieve portable precision I should check SELECTED_REAL_KIND (or _INT_) with my required precision and range, and according to results of those, adjust my KIND parameter ?
> So, if I wish to achieve portable precision I should check > SELECTED_REAL_KIND (or _INT_) with my required precision and range, > and according to results of those, adjust my KIND parameter ?
...
Yeah, but don't actually use the KIND value itself, keep to the PARAMETER. Then you don't have to change between compilers (the point of introducing the syntax)
See Dick H's response on the logic behind the use of the intrinsics; I'll not try to repeat is succinct explanation...
Dick Hendrickson <dick.hendrick...@att.net> wrote: > Luka Djigas wrote: > > I'm looking over some examples from Ramsden & Lin's "Fortran 90 > > conversion course for F77 programmers", and glancing over the chapter > > which shows KIND parameter. I've never used it before, sticking to old > > DOUBLE PRECISION when it was needed. ... > > INTEGER, PARAMETER :: idp = KIND(1.0D) ... > > Also, the mentioned compilers do not seem to support KIND=2 type. > Unless I'm missing something, the first line looks OK. Could you > show the actual results? Are you sure you aren't compiling > in fixed form mode rather than free form?
That was my thought as well. Both Dick's and my eyes missed the omission of the 0 from D0, which Reubendb caught.
> There is no particular standard meaning for KIND=2, it certainly > isn't guaranteed to be double precision.
I haven't seen the particular book in question, but I'd be a bit dissapointed at any book that suggested using explicit kind numbers such as 2. No explicit kind numbers are specified by the standard, and 2 isn't even the most common choice for double precision.
If the OP is looking for a book aimed at upgrading from f77, I am quite fond of Cooper Redwine's "UPgrading to Fortran 90". It is no longer in print, but can often be found. (Wow, I see that Amazon shows quite premium prices for used copies! I suppose that probably reflects something about the demand.)
> The purpose of the KIND system is to allow you to specify what > you need or want for the precision of floating point variables.
Also, a thing that I particularly like about the KIND system is its consistency. (A thing that I dislike about it is the use of integers for KIND numbers, which promulgates nonportable practices as well as just plain mistakes; oh well). Look at what is involved in adding a new precision, such as the quad precision that is moderately common these days. With the "old-fashioned" way, this involves quite a lot of new syntax. You need a new declaration statement, an exponent letter (certainly in the source code, and often also for formatted I/O), a bunch of new intrinsic names, and I forget what else.
Try taking a program that was written for one precision and converting it to use another one. That can come up for many reasons. Perhaps you are on a compiler where single and double precision are different from the compiler the code was written for. Or perhaps you are applying the code to problems that require larger precision than the probleme envisioned when the code was written. In my youth, I used to spend quite a lot of time doing precision conversions like that (most often as a consequence of moving to a new computer with a different default precision). I can testify that it can be a *LOT* of work in some cases. It is possible to write code that converts easily, but you have to be very deliberate about the intention of making it easy to convert.
With KIND parameters, you can define the kind parameter value on a single line in a module. Then it is a one-line change to convert the entire program. (Ok, programs that use multiple precisions can be more complicated than that in some cases.) All the syntax is unchanged; the same syntax works for single, double, quad, or any other oddball precision that you might have.
-- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain
> So, if I wish to achieve portable precision I should check > SELECTED_REAL_KIND (or _INT_) with my required precision and range, > and according to results of those, adjust my KIND parameter ?
Do something like this:
MODULE Type_Kinds IMPLICIT NONE PRIVATE PUBLIC :: Byte, Short, Long PUBLIC :: Single, Double
INTEGER, PARAMETER :: Byte = SELECTED_INT_KIND(1) ! Byte integer INTEGER, PARAMETER :: Short = SELECTED_INT_KIND(4) ! Short integer INTEGER, PARAMETER :: Long = SELECTED_INT_KIND(8) ! Long integer
INTEGER, PARAMETER :: Single = SELECTED_REAL_KIND(6) ! Single precision INTEGER, PARAMETER :: Double = SELECTED_REAL_KIND(15) ! Double precision END MODULE Type_Kinds
and then USE the above module everywhere you need explicit types,
PROGRAM blah USE Type_Kinds, fp=>Double IMPLICIT NONE REAL(fp) :: x
x = 3.14159_fp ..... END PROGRAM
You'll then have a portable way to define all your intrisic int and float types.
If you want to switch to single prevision, change the USE statement in your app to, USE Type_Kinds, fp=>Single
On Fri, 8 May 2009 10:27:25 -0700, nos...@see.signature (Richard
Maine) wrote:
>I haven't seen the particular book in question, but I'd be a bit >dissapointed at any book that suggested using explicit kind numbers such >as 2. No explicit kind numbers are specified by the standard, and 2 >isn't even the most common choice for double precision.
Actually, it isn't a book but a 'scripta' (latin). I didn't know how to say it in english correctly so it comes out in the right context. A pamphlet, a "textbook" maybe - yes, that would probably be pretty close.
They don't suggest using explicit kind numbers. I've rather ankwardly expressed myself there - they don't assume that kind=2 would be double precision either. That was a completely different question whatsoever, just putted behind the first one in a manner that it was understood in context of the first one - I was curious why the compiler didn't support it.
>> The purpose of the KIND system is to allow you to specify what >> you need or want for the precision of floating point variables.
>Also, a thing that I particularly like about the KIND system is its >consistency. (A thing that I dislike about it is the use of integers for >KIND numbers, which promulgates nonportable practices as well as just >plain mistakes; oh well).
Could you explain this a little ?
I fail to see how those integers are important at all ... they are just a means of expressing what KIND is needed for wanted precision. I guess those numbers could be real's as well, but I cannot see the advantage in that approach.
I must be missing something here.
>Look at what is involved in adding a new >precision, such as the quad precision that is moderately common these >days. With the "old-fashioned" way, this involves quite a lot of new >syntax. You need a new declaration statement, an exponent letter >(certainly in the source code, and often also for formatted I/O), a >bunch of new intrinsic names, and I forget what else.
Ughh, yes, unfortunatelly, I've done it a few times, but never *liked* doing it. I've always had the feeling that I missed something somewhere.
>Try taking a program that was written for one precision and converting >it to use another one. That can come up for many reasons. Perhaps you >are on a compiler where single and double precision are different from >the compiler the code was written for. Or perhaps you are applying the >code to problems that require larger precision than the probleme >envisioned when the code was written. In my youth, I used to spend quite >a lot of time doing precision conversions like that (most often as a >consequence of moving to a new computer with a different default >precision). I can testify that it can be a *LOT* of work in some cases. >It is possible to write code that converts easily, but you have to be >very deliberate about the intention of making it easy to convert.
>With KIND parameters, you can define the kind parameter value on a >single line in a module. Then it is a one-line change to convert the >entire program. (Ok, programs that use multiple precisions can be more >complicated than that in some cases.) All the syntax is unchanged; the >same syntax works for single, double, quad, or any other oddball >precision that you might have.
Yes, Paul van Delst gave an example in his post, which is very nice in illustrating that view.
On Fri, 08 May 2009 16:45:36 GMT, Dick Hendrickson
<dick.hendrick...@att.net> wrote: >Unless I'm missing something, the first line looks OK. Could you >show the actual results? Are you sure you aren't compiling >in fixed form mode rather than free form?
Quite sure. But, either way, would it make a difference ?
>There is no particular standard meaning for KIND=2, it certainly >isn't guaranteed to be double precision. Most processors now >use kind numbers that are related to bytes; 4 for single, 8 for >double. But, that isn't required.
No, no. I've putted this in a rather ankward way. I didn't mean to suggest that KIND=2 would be double precision. I was just suprised that they didn't support it.
>The purpose of the KIND system is to allow you to specify what >you need or want for the precision of floating point variables. >Specifying KIND(1.0D0) is just another way of spelling >DOUBLE PRECISION. You're usually better off to use the >SELECTED_REAL_KIND intrinsic and specify something like
>and then you're guaranteed to get 13+ digits of precision on >all processors. Specifying DOUBLE PRECISION (or KIND(1.0D0)) >is likely to get you 26 digits of precision on a machine whose >native floating point mode is 64 or 128 bits rather than the >more common 32/62 bits. That's likely to be noticeably slower.
I understood the point about the SELECTED_ functions, but the one about the processor's "number of bits" escaped me. I thought that single precision on 32-bit cpu's ment 13+ safe digits, and double twice that.
Could I bother you to explain a little more how the processor's "number of bits" effects precision when using SELECTED_ functions ? I'm under the impression that if I use SELECTED_ to determine the kind value, I don't need to worry about cpu's "number of bits".
Luka Djigas <ldigas@@gmail.com> wrote: > On Fri, 8 May 2009 10:27:25 -0700, nos...@see.signature (Richard > Maine) wrote: > >(A thing that I dislike about it is the use of integers for > >KIND numbers, which promulgates nonportable practices as well as just > >plain mistakes; oh well).
> Could you explain this a little ?
> I fail to see how those integers are important at all ... they are > just a means of expressing what KIND is needed for wanted precision. > I guess those numbers could be real's as well, but I cannot see the > advantage in that approach.
> I must be missing something here.
No, they wouldn't be reals. That would be just as bad (and probably worse). The problem with them being integers (or any numeric type) is that it provides no error protection. You can do completely inappropriate things with them and the compiler likely won't catch it because it isn't technically an error of the kind that won't compile, even if it happens to have nothing to do with what you intended.
There is an excellent example of exactly this in another thread that is active right now on this newsgroup. It is so good an example that you might think I planted it for the purpose. (I didn't). Someone took a kind parameter for a character character kind parameter and used it inappropriately as a kind parameter for an integer (possibly influenced by C conflation of character and integer). It is basically nonsense to use a kind parameter for a character that way, but because kind parameter values are just ordinary integers, there is nothing to say that such a thing is actually invalid. It is pretty much nonsense by definition, but it is nonsense that the compiler is actually required to allow.
The idea would instead be to have a derived type for each kind parameter. You then could not accidentally do arithmetic on them or accidentally use some other random integer expression for a kind value. The *ONLY* things that would be allowable as integer kind values would be things that had the derived type defined for integer kind values. If you made the mistake of using a kind value that was supposed to be for a character, it would be of the wrong type and you'd get a compilation error. In fact, apparently one of the compilers tested tried to do something like that and throw an error for the inappropriate usage. Unfortunately, with Fortran defined as it is today, that bit of compiler help counts as a compiler bug.
Another advantage is that you wouldn't have to continually caution people about how the standard doesn't specify particular numeric values for kind parameters. The question just wouldn't come up at all.
The above are practical issues, but I think there is a more fundamental conceptual one of integers being inappropriate to model kind parameters. In my view, the practical problems are a consequence of the conceptual mismatch. Integers are numeric and have all kinds of numeric properties. Those numeric properties are not a good match for kind parameters. It generally doesn't make any sense to be doing addition, multiplication, exponentiation, and Lord knows what else with kind parameter values.
This isn't going to happen. I'm not making it as a serious proposal because that would just waste the time of all concerned, debating about something that isn't going to happen. Likewise, I'm not filling in the fine points of detail because it seems pointless to work out the fine points of something that won't happen. This is just explaining a rough outline of the direction I wish it had been taken.
-- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain
> I understood the point about the SELECTED_ functions, but the one > about the processor's "number of bits" escaped me. > I thought that single precision on 32-bit cpu's ment 13+ safe digits, > and double twice that.
About 3.32 bits per decimal digit. (1./log10(2.)). 32 bit float has about 24 digits of significand for 7.2 decimal digits.
> Could I bother you to explain a little more how the processor's > "number of bits" effects precision when using SELECTED_ functions ? > I'm under the impression that if I use SELECTED_ to determine the kind > value, I don't need to worry about cpu's "number of bits".
The kind values give the appropriate KIND, if any, for the specified number of significant decimal digits or exponent range.
If you know the exact precision required (rare) then you can specify that with SELECTED_REAL_KIND and use the appropriate kind. If you ask for more than the processor can supply, then SELECTED_REAL_KIND returns -1 and compilation fails.
Some people would like the ability to specify the number of bits required, which may not represent an integer number of digits. Fortran as yet doesn't have that ability. (I believe not in 2008, though I am not so sure about that.)
Luka Djigas wrote: > On Fri, 08 May 2009 16:45:36 GMT, Dick Hendrickson > <dick.hendrick...@att.net> wrote:
>> Unless I'm missing something, the first line looks OK. Could you >> show the actual results? Are you sure you aren't compiling >> in fixed form mode rather than free form?
> Quite sure. > But, either way, would it make a difference ?
With the program you showed, beginning in column 1 or 2, it would make a big difference. I had missed the fact that there was no "0" after the "D" in the statement and was just trying to guess what the error might be. Free form source generally gives lots of syntax errors because of punches in columns 1 through 5. They are reserved for statement labels in fixed source form. It's surprising how often specifying the correct source form on the command line is the solution to problems here ;).
>> There is no particular standard meaning for KIND=2, it certainly >> isn't guaranteed to be double precision. Most processors now >> use kind numbers that are related to bytes; 4 for single, 8 for >> double. But, that isn't required.
> No, no. I've putted this in a rather ankward way. I didn't mean to > suggest that KIND=2 would be double precision. > I was just suprised that they didn't support it.
But, there's no reason to be surprised. The KIND numbers aren't directly related to anything specific in the hardware or processor. They're an arbitrary "tag" chosen by the compiler writer to "name" the precisions they have chosen to support. As I said, the KIND numbers often are the same as the number of bytes in the entity. Many compilers support KIND=2 as a 16 bit integer; but almost none would support a 16 bit floating point value. Many years ago, some processors used kind=1 for single precision and kind=2 for double. Some still do, although they usually have a command line switch that lets the programmer choose between 1/2 or 4/8 for the kind numbers. The switch lets people who have put in fixed numbers for the kinds compile their programs.
>> The purpose of the KIND system is to allow you to specify what >> you need or want for the precision of floating point variables. >> Specifying KIND(1.0D0) is just another way of spelling >> DOUBLE PRECISION. You're usually better off to use the >> SELECTED_REAL_KIND intrinsic and specify something like
>> and then you're guaranteed to get 13+ digits of precision on >> all processors. Specifying DOUBLE PRECISION (or KIND(1.0D0)) >> is likely to get you 26 digits of precision on a machine whose >> native floating point mode is 64 or 128 bits rather than the >> more common 32/62 bits. That's likely to be noticeably slower.
> I understood the point about the SELECTED_ functions, but the one > about the processor's "number of bits" escaped me. > I thought that single precision on 32-bit cpu's ment 13+ safe digits, > and double twice that.
Actually, 32 bit single precision is about 7 digits, not 13.
> Could I bother you to explain a little more how the processor's > "number of bits" effects precision when using SELECTED_ functions ? > I'm under the impression that if I use SELECTED_ to determine the kind > value, I don't need to worry about cpu's "number of bits".
True, you don't have to worry about the number of bits. But, ultimately you can only get precisions that the hardware supports. The SELECTED_* functions give you a portable way to determine what KIND value you should use on a processor. And, they do it in a portable way that doesn't require any programming changes when you move to a different compiler or computer.
To get a feeling for what the selected_* functions do, try running the following program (I haven't actually tried it myself, you'll probably have to debug it some :( )
program show_kinds do I = 1,50 J = selected_integer_kind(I) K = selected_real_kind(I) L = selected_real_kind(I,200) print "(4I5)", I,J,K,L enddo end program
> Dick Hendrickson <dick.hendrick...@att.net> wrote: >> The purpose of the KIND system is to allow you to specify what >> you need or want for the precision of floating point variables.
> Also, a thing that I particularly like about the KIND system is its > consistency. (A thing that I dislike about it is the use of integers for > KIND numbers, which promulgates nonportable practices as well as just > plain mistakes; oh well). Look at what is involved in adding a new > precision, such as the quad precision that is moderately common these > days. With the "old-fashioned" way, this involves quite a lot of new > syntax. You need a new declaration statement, an exponent letter > (certainly in the source code, and often also for formatted I/O), a > bunch of new intrinsic names, and I forget what else.
> Try taking a program that was written for one precision and converting > it to use another one. That can come up for many reasons. Perhaps you > are on a compiler where single and double precision are different from > the compiler the code was written for. Or perhaps you are applying the > code to problems that require larger precision than the probleme > envisioned when the code was written. In my youth, I used to spend quite > a lot of time doing precision conversions like that (most often as a > consequence of moving to a new computer with a different default > precision). I can testify that it can be a *LOT* of work in some cases. > It is possible to write code that converts easily, but you have to be > very deliberate about the intention of making it easy to convert.
> With KIND parameters, you can define the kind parameter value on a > single line in a module. Then it is a one-line change to convert the > entire program. (Ok, programs that use multiple precisions can be more > complicated than that in some cases.) All the syntax is unchanged; the > same syntax works for single, double, quad, or any other oddball > precision that you might have.
It's still a little unclear to me how to manage kinds in the context of a program that uses multiple libraries, each with their own working precision kind parameters defined.
In the context of a single self-contained program or library, I would simply define a working precision kind parameter and use it uniformly throughout the program. For a program which uses a single external library, say LAPACK95, I would probably use the precision parameters defined by the library:
use la_precision, only: wp
However, what do you do when you need to use multiple libraries? (Or, when you're designing a library that would likely be used with others?) Let's say that library_a defined
In some cases these will be the same, but you can't assume they will be.
What kind should you use in your program? If, say, you use the precision from library_a:
program main use library_a, wp => a_wp use library_b implicit none
real(wp) :: x, y
What happens if I call a routine from library_b using x and y if the kinds happen to be different?
call b_routine(x, y)
Is this handled automatically by casting or does it only work if the kind parameters are identical?
I guess my main questions are what are the best practices for selecting kind parameters when designing a library (I tend to like the renaming facility of LAPACK95) and how should you handle (potentially) different precisions from different libraries in a single program?
-- Jason Blevins Ph.D. Candidate, Department of Economics, Duke University http://jblevins.org
Jason Blevins <jrble...@sdf.lonestar.org> wrote: > It's still a little unclear to me how to manage kinds in the context of > a program that uses multiple libraries, each with their own working > precision kind parameters defined.
> In the context of a single self-contained program or library, I would > simply define a working precision kind parameter and use it uniformly > throughout the program. For a program which uses a single external > library, say LAPACK95, I would probably use the precision parameters > defined by the library:
> use la_precision, only: wp
> However, what do you do when you need to use multiple libraries?
Most commonly, you would not use precision parameters from such libraries at all. You would use your own precision parameters. The library should have generic procedure names, so you just invoke the procedures with their generic names and you will get the right version for whatever precision you are using. This doesn't involve using precision parameters from the library at all.
If you aren't familiar with generic procedures, you'll likely be confused by the above because generics are the crux of the whole idea.
And it is important to note that you do not need to use the kind parameter
> (Or, when you're designing a library that would likely be used > with others?)
Now that's more work, particularly when you have to deal with supporting multiple environments that have different numbers of precision options (notably if some of the environments have a quad real and others don't). I don't think I'll try to go into that one here. It is a harder question (but fortunately, one that fewer people have to deal with; it's a question for the library writers more than for the library users).
> What happens if I call a routine from library_b using x and y > if the kinds happen to be different?
> call b_routine(x, y)
> Is this handled automatically by casting or does it only work if the > kind parameters are identical?
There is no casting in Fortran. (There are some mixed-mode operations, but that's not the same thing). The actual and dummy arguments must match. The library could choose to explicitly provide a version of the subroutine that had the mixed kinds, but that would pretty quickly get out of hand in the general case. That's much of why I talk about the precision used on a whole application basis. You can't expect to indivually select the precision of every separate object in your program and get anything but a mess. (Besides, it would be too much bother to go through deciding exactly what each object needed.) Instead, you select a precision that pretty much the whole app will use for most things; you can have exceptions where something uses a different precision, but they need to be a relatively small number of exceptions to keep things under control.
-- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain
> I'm looking over some examples from Ramsden & Lin's "Fortran 90 > conversion course for F77 programmers", and glancing over the chapter > which shows KIND parameter. I've never used it before, sticking to old > DOUBLE PRECISION when it was needed.
> onto which cvf66c and ifort gave an error, reporting syntax error in > the first line (INTEG .... 1.0D)
It must be 1.0D0
> Also, the mentioned compilers do not seem to support KIND=2 type. Is > there something I'm doing wrong, or is the mentioned book just written > for some other compiler?
You don't need to specify any kind numbers. Doing so can make the program non-portable.
All that's necessary is to specify something like:
> On Fri, 8 May 2009 09:37:47 -0700 (PDT), reubendb <reube...@gmail.com> > wrote:
> >Hello,
> >On May 8, 11:52 am, Luka Djigas <ldigas@@gmail.com> wrote:
> >> INTEGER, PARAMETER :: idp = KIND(1.0D)
> >This should be > >INTEGER, PARAMETER :: idp = KIND(1.0D0) > > ^^^ > >notice that you're missing the exponent for the number.
> Ah, I see. > Must've been a mistype in the book.
> >> Also, the mentioned compilers do not seem to support KIND=2 type. Is > >> there something I'm doing wrong, or is the mentioned book just written > >> for some other compiler?
> >The value of KIND is internal representation of the compiler. It's not > >necessarily portable, so different compiler may have different value > >of KIND to represent the same precision. i.e the result of : > >WRITE(*,*)KIND(ra) > >may be different for different compiler.
> >So the way to select the KIND is by doing what you have in the > >example, or using function such as selected_int_kind() or > >selected_real_kind().
> So, if I wish to achieve portable precision I should check > SELECTED_REAL_KIND (or _INT_) with my required precision and range, > and according to results of those, adjust my KIND parameter ?
Yes. But what you originally wrote is OK too [with minor correction, of course].
> I understood the point about the SELECTED_ functions, but the one > about the processor's "number of bits" escaped me. > I thought that single precision on 32-bit cpu's ment 13+ safe digits, > and double twice that.
Typically, single precision (32 bits) gives about 6 decimal digits, while double precision gives about 15 digits.
According to Chapman, it would be better to specify the numer of digits that you need instead of using "1.0D0" or "1.0E0", since the concept of single/double precision is different among compilers.
This is an example: INTEGER, PARAMETER :: sp = SELECTED_REAL_KIND(p=6) INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(p=15) INTEGER, PARAMETER :: ep = SELECTED_REAL_KIND(p=18) INTEGER, PARAMETER :: qp = SELECTED_REAL_KIND(p=33)
sp -> single precision, 32 bit dp -> double precision, 64 bit ep -> extended precision, 80 bit (only for x86) qp -> quadruple precision, 128 bit
On Fri, 8 May 2009 22:33:50 -0700, nos...@see.signature (Richard
Maine) wrote:
<snip: kind numbers>
> No, they wouldn't be reals. That would be just as bad (and probably > worse). The problem with them being integers (or any numeric type) is > that it provides no error protection. You can do completely > inappropriate things with them and the compiler likely won't catch ...
<snip: (distinct) derived types instead>
> In fact, apparently one of the compilers tested tried to do > something like that and throw an error for the inappropriate usage. > Unfortunately, with Fortran defined as it is today, that bit of compiler > help counts as a compiler bug.
Even with integers, I think an implementor could use disjoint ranges. (Actually, disjoint values is enough, but ranges is easier to explain and keep straight.) E.g. use 100,101,... for integer kinds, 200,201,... for real (&cplx), 300,301,... for chars, etc.
> Another advantage is that you wouldn't have to continually caution > people about how the standard doesn't specify particular numeric values > for kind parameters. The question just wouldn't come up at all. > [and...] It generally doesn't make any sense to be doing addition, multiplication, > exponentiation, and Lord knows what else with kind parameter values.