|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
pierre
Joined: 04 Feb 2007 Posts: 24
|
Posted: Mon Feb 12, 2007 4:15 pm Post subject: Precision and FTN95 |
|
|
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...........)
2) 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 ? |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7928 Location: Salford, UK
|
Posted: Mon Feb 12, 2007 5:59 pm Post subject: |
|
|
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. |
|
Back to top |
|
|
pierre
Joined: 04 Feb 2007 Posts: 24
|
Posted: Wed Feb 14, 2007 3:29 pm Post subject: |
|
|
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) |
|
Back to top |
|
|
DrTip
Joined: 01 Aug 2006 Posts: 74 Location: Manchester
|
Posted: Wed Feb 14, 2007 4:02 pm Post subject: |
|
|
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 |
|
Back to top |
|
|
pierre
Joined: 04 Feb 2007 Posts: 24
|
Posted: Wed Feb 14, 2007 4:08 pm Post subject: |
|
|
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. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7928 Location: Salford, UK
|
Posted: Wed Feb 14, 2007 8:11 pm Post subject: |
|
|
DO is D followed by the number zero. |
|
Back to top |
|
|
pierre
Joined: 04 Feb 2007 Posts: 24
|
Posted: Wed Feb 14, 2007 9:15 pm Post subject: |
|
|
I know and I tried both D0 and DO |
|
Back to top |
|
|
JohnHorspool
Joined: 26 Sep 2005 Posts: 270 Location: Gloucestershire UK
|
Posted: Wed Feb 14, 2007 9:20 pm Post subject: |
|
|
...and I thought the DODO was extinct !
(sorry couldn't resist!) |
|
Back to top |
|
|
pierre
Joined: 04 Feb 2007 Posts: 24
|
Posted: Wed Feb 21, 2007 3:27 pm Post subject: |
|
|
What is the difference between D0 and _2 ? |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7928 Location: Salford, UK
|
Posted: Wed Feb 21, 2007 5:37 pm Post subject: |
|
|
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. |
|
Back to top |
|
|
pierre
Joined: 04 Feb 2007 Posts: 24
|
Posted: Wed Feb 21, 2007 5:41 pm Post subject: |
|
|
Thanks a lot for those clear explanations. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Tue Feb 27, 2007 1:13 am Post subject: |
|
|
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
!
integer*4, parameter :: i1 = selected_int_kind(2)
integer*4, parameter :: i2 = selected_int_kind(4)
integer*4, parameter :: i4 = selected_int_kind(9)
integer*4, parameter :: i8 = selected_int_kind(1
!
integer*4, parameter :: re = selected_real_kind(6,0)
integer*4, parameter :: rd = selected_real_kind(15,0)
integer*4, 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 real*4
aq(2) = 0.1e0 ! real*4
aq(3) = 0.1d0 ! real*8
aq(4) = 0.1_rq ! real*10
write (*,*) 'Array aq', aq
end |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7928 Location: Salford, UK
|
Posted: Tue Feb 27, 2007 10:32 am Post subject: |
|
|
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. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Wed Feb 28, 2007 1:59 am Post subject: |
|
|
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 |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7928 Location: Salford, UK
|
Posted: Wed Feb 28, 2007 8:30 am Post subject: |
|
|
John
Thank you for your comments.
The default for INTEGERs is KIND=3. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|