Silverfrost Forums

Welcome to our forums

Precision and FTN95

12 Feb 2007 3:15 #1651

There are two issue:

1)I declare: REAL*8, DIMENSION(1:3) :: X

X=(/ 1.20, 3.40, 3.0 /)

When I read X in the debugger I see; X(1)=1.20000002134598

X(2)=3.40000003443234

X(3)=3.00000000000000

The two first number are not what I have declared ....... (Worst when I use 4.10 I get 4.099...........)

  1. When I declare REAL*4, DIMENSION(1:3) :: X

X(1)=1.0*10.0**(-16)

I obtain in the debugger; X(1)=1.000000e-16

Which is good but mathematically impossible since single precision can only go up to 10^-8 (if I remember well)

So here is my question; How is precision managed in this compiler ?

12 Feb 2007 4:59 #1652

You need 1.20D0 etc. or 1.20_2 for double precision constants (this is standard Fortran syntax not FTN95).

The minimum exponent is -125 for single precision, see the help file FTN95.chm under Kind parameters for intrinsics types->Real KINDs.

14 Feb 2007 2:29 #1660

I followed your advice and I tried;

REAL*8, DIMENSION(1:7) :: X

X(1:7)=(/0.5,2.544604382862076E-002_2 ,0.129234407200303_2 , 0.297077424311301_2,0.702922575688699_2 , 0.870765592799697_2 ,0.974553956171379_2 /)

But I get the answer; You cannot have a REAL(KIND=2) constant, such as 0.025446043828621_2, in a REAL(KIND=1) array constructor

How do I build my REAL(KIND=2) array (whithout doing X(k)=...... 7 times)

14 Feb 2007 3:02 #1661

pierre

first an observation you have missed the _2 of your first element

and I think therefore is you problem, I think this is an example of a misleading compiler message.

because the first element is not a double it assumes the array is single precision. hence the message

this code works for me

program test

real*8 :: testarray(3) integer i

testarray=(/0.5_2 ,0.6_2 , 0.7_2/)

write(,) testarray

call get_key@(i)

end program

14 Feb 2007 3:08 #1662

You are absolutly right. It works now ! Thank you

edit: but if you use (/0.5D0 ,0.6D0 , 0.7D0/) , the compiler think D0 is a variable.

14 Feb 2007 7:11 #1665

DO is D followed by the number zero.

14 Feb 2007 8:15 #1667

I know and I tried both D0 and DO

14 Feb 2007 8:20 #1668

...and I thought the DODO was extinct !

(sorry couldn't resist!)

21 Feb 2007 2:27 #1727

What is the difference between D0 and _2 ?

21 Feb 2007 4:37 #1728

Not a lot.

'D0' is Fortran 77 (and probably Fortran 66. I do not remember). '_2' is Fortran 90 but the 2 is the KIND value which is compiler dependent.

Array constructors are Fortran 90 so it is quite possible that FTN95 will not allow you to use 'D0' in them.

'D' is the same as the exponent marker 'E' but for double precision.

21 Feb 2007 4:41 #1729

😄 Thanks a lot for those clear explanations.

27 Feb 2007 12:13 #1746

I tried to provide the following sample code below to demonstrate the different kinds of real precision. hopefully the last line of output demonstrates the different precision effects. I then tried to compile the program using /alt_kinds and got a number of errors, as it appears that selected_real_kind might return the salford default values ? I still try to avoid 0.1_3 in my codes.

This code is:

! Test possible values of kind selection ! integer4, parameter :: i1 = selected_int_kind(2) integer4, parameter :: i2 = selected_int_kind(4) integer4, parameter :: i4 = selected_int_kind(9) integer4, parameter :: i8 = selected_int_kind(18) ! integer4, parameter :: re = selected_real_kind(6,0) integer4, parameter :: rd = selected_real_kind(15,0) integer4, parameter :: rq = selected_real_kind(18,0) ! real(rq) :: xq = 0.1 real(rq), dimension(4) :: aq ! write (,) 'Integer kind = ', i1,i2,i4,i8 write (,) 'Real kind = ', re, rd, rq ! write (,2000) 'Real Kind rq = selected_real_kind(18,0)' write (,2001) 'kind = ', kind(xq) write (,2001) 'kind parameter = ', rq write (,2001) 'precision = ', precision(xq) write (,) 'huge = ', huge(xq) write (,2001) 'binary digits = ', digits(xq) write (,2001) 'range = ', range(xq) ! 2000 format (/a) 2001 format (1x,a,i0) ! write (,2000) 'rq array ( .1_rq, .2_rq, .3_rq, .4_rq )' aq = (/ 0.1_rq, 0.2_rq, 0.3_rq, 0.4_rq /) write (,) 'Array aq', aq ! write (,2000) 'rq array ( .1, .1e0, .1d0, .1_rq )' aq(1) = 0.1 ! default to real4 aq(2) = 0.1e0 ! real4 aq(3) = 0.1d0 ! real8 aq(4) = 0.1_rq ! real10 write (,*) 'Array aq', aq end

27 Feb 2007 9:32 #1747

selected_real_kind gives the compiler kinds. These values are not changed by using /alt_kinds.

With /alt_kinds, real(rq) fails because rq = 3 and this is not a valid alt_kind value.

In short, if you are using selected_real_kind etc. then there is no reason to use /alt_kinds and, as you say, it does not work.

I assume that this is by design, although it might be due to an oversight. If there is a good reason for changing please let me know. Maybe we should change it anyway to make the whole thing consistent.

28 Feb 2007 12:59 #1753

Paul,

The compiler option /alt_kinds provides for greater portability of fixed value kind, although when the ftn95 standard did not define kind values, this removed the portability that had always been targeted.

The definition of real*10 constants becomes a problem. Values, such as 0.1_3 are not portable, where as 0.1_rq is, but is not clear in it's meaning.

It would have been good if, like other fortran vendors, Salford took kind values to be the number of bytes. Salford also has that kind=1 is the default kind value, which causes problems for integer*1. This has not been adopted by Lahey/Fujitsu or Intel, and I'm not sure of the others.

To date, I have rarely used /alt_kinds and when required, I have resorted to the use of selected_real_kind parameters to maintain portability.

regards John

28 Feb 2007 7:30 #1754

John

Thank you for your comments. The default for INTEGERs is KIND=3.

Please login to reply.