replica nfl jerseysreplica nfl jerseyssoccer jerseyreplica nfl jerseys forums.silverfrost.com :: View topic - Extended precision
forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Extended precision

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General
View previous topic :: View next topic  
Author Message
Konstantin8



Joined: 07 Jun 2013
Posts: 9

PostPosted: Mon Jun 10, 2013 12:39 pm    Post subject: Extended precision Reply with quote

Sorry for this question but unfortunately I cannot find any "clear" information...
Is there any ability to work with extended precision (real*10)?

I wrote the following:
real*10 A

then I try to use sqrt for A.

But unfortunately it's not possible.

Could anybody give me an advice?Smile

Thanks!
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2621
Location: Sydney

PostPosted: Mon Jun 10, 2013 1:14 pm    Post subject: Reply with quote

The following simple code works ok for me
Code:
real*10 a,b
!
a = 8
b = sqrt (a)
write (*,*) a,b, b/2
end
Back to top
View user's profile Send private message
Konstantin8



Joined: 07 Jun 2013
Posts: 9

PostPosted: Mon Jun 10, 2013 1:22 pm    Post subject: Re: Reply with quote

JohnCampbell wrote:
The following simple code works ok for me
Code:
real*10 a,b
!
a = 8
b = sqrt (a)
write (*,*) a,b, b/2
end



Hm, thanks)
will try...

I used "*D*sqrt"....Smile
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2621
Location: Sydney

PostPosted: Tue Jun 11, 2013 1:05 am    Post subject: Reply with quote

The following code might better demonstrate the precision of the alternative real kinds available in ftn95
Code:
real*10 a,b
real*8  c,d
real*4  e,f
!
write (*,*) '!  sqrt_two  =                                                 1.4142135623730950488016887242096980_16  = SQRT (2)'

a = 8
b = sqrt (a)
write (*,2010) '*10',a,b, b/2, (b/2)**2
!
c = 8
d = sqrt (c)
write (*,2008) '*8 ',c,d, d/2, (d/2)**2
!
e = 8
f = sqrt (e)
write (*,2004) '*4 ',e,f, f/2, (f/2)**2
2010 format (a4, f27.19,3f27.19)
2008 format (a4, f24.16,3f27.16)
2004 format (a4, f16.8, 3f27.8)
end

I've pushed the output precision until sqrt(2) is wrong in the last digit.

Note that b/2 retains the real*10 precision, as integer 2 is an exact binary representation of 2.0_4, while 0.1_2 is different from 0.1_3 or 0.1_4.

real*10 does offer better precision than real*8, but I have found it difficult to maintain the precision, especially with mixed kind calculations. If your calculation is not stable with real*8, then going to real*10 might not be the best solution. Changing the calculation formulation, or even the order of calculation might improve round-off growth.
For infinite series with alternating sign, it can be useful to do the calculation in pairs to overcome subtracting similar values, although the round-off improvement is often marginal.

John
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2937
Location: South Pole, Antarctica

PostPosted: Thu Jun 13, 2013 3:24 pm    Post subject: Reply with quote

I had the code waiting for extended precision for ages and i gave it a try today.

Just for info, the machine ESP for real*10 is in the region of 5*10^-20 which can be taken from this simple code
Code:

   real*10 Eps, tol
   EPS=1.D0
10 Eps=Eps/2.D0
   Tol=1.d0+Eps
   if (Tol.GT.1.d0) goto 10
   Write (*,*)' Eps REAL*10=', Eps
   end


but what interesting for me is that the exponent can go beyond the crazy values like 10^4000:

Code:

   a=1
   do i=1,20000
   a=a*2
   write (*,*)'Max=', a
   enddo

Question is though: how to use this extended range of exponents in the codes because compiler swears with the message "*** Floating point number out of range *** Compilation abandoned you moron" for that kind of lines
Code:
if(SumP.GT.1.d3000) goto  2


Use those annoying REAL_KINDs 3?
integer, parameter :: rkind=selected_real_kind(18,4931)
How correctly set it up?
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 8254
Location: Salford, UK

PostPosted: Thu Jun 13, 2013 3:58 pm    Post subject: Reply with quote

If you declare REAL(3)::x then the compiler will provide a useful comment to tell you what to use in place of 3.
Back to top
View user's profile Send private message AIM Address
DanRRight



Joined: 10 Mar 2008
Posts: 2937
Location: South Pole, Antarctica

PostPosted: Thu Jun 13, 2013 4:55 pm    Post subject: Reply with quote

Thanks. I also found something relevant in the Help, but will this fix the error i've got?
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 8254
Location: Salford, UK

PostPosted: Thu Jun 13, 2013 5:20 pm    Post subject: Reply with quote

I don't think so. You will need to write code that avoids overflow.
You can probably trap the exception if it occurs at run time but I don't see how that will help.
Back to top
View user's profile Send private message AIM Address
DanRRight



Joined: 10 Mar 2008
Posts: 2937
Location: South Pole, Antarctica

PostPosted: Thu Jun 13, 2013 5:23 pm    Post subject: Reply with quote

But that is not an error and not an under/overflow! This is completely legitimate code which got these kind of too large or too small numbers due to tricky method of solution! And these sort of crazy numbers were in the FP coprocessors since IBM PC XT, we just never used them because compilers did not allow that

Last edited by DanRRight on Thu Jun 13, 2013 5:29 pm; edited 1 time in total
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 8254
Location: Salford, UK

PostPosted: Thu Jun 13, 2013 5:29 pm    Post subject: Reply with quote

Maybe you should use constants with the corresponding KIND.

e.g. x = 1.0_3
Back to top
View user's profile Send private message AIM Address
DanRRight



Joined: 10 Mar 2008
Posts: 2937
Location: South Pole, Antarctica

PostPosted: Thu Jun 13, 2013 5:44 pm    Post subject: Reply with quote

Alas, compiler still gives an error that floating point number out of rangeBad value for exponent. I suspect the limit in compiler is done for real*8 numbers and is explicitly wired somewhere in the source
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2621
Location: Sydney

PostPosted: Fri Jun 14, 2013 1:49 am    Post subject: Reply with quote

Dan,

I'd like to see the example which fails with bad exponent value, including declarations.
I think you have to be careful with constant definition, to ensure the implied precision. The following example code fails for the last two lines, but the previous 3 do work.

Code:
module kind_precision
   integer, parameter :: int_1byte   = selected_int_kind (2)         ! 1
   integer, parameter :: int_2byte   = selected_int_kind (4)         ! 2
   integer, parameter :: int_4byte   = selected_int_kind (9)         ! 3
   integer, parameter :: int_8byte   = selected_int_kind (18)        ! 4
   integer, parameter :: real_float  = selected_real_kind (6,37)     ! 1
   integer, parameter :: real_double = selected_real_kind (15,307)   ! 2
   integer, parameter :: real_long   = selected_real_kind (18,4931)  ! 3
end module kind_precision

use kind_precision
!
   integer ( kind=int_4byte ) :: i,k, last_k
   character kind_name*10
   real ( kind=real_double ) :: x
   real ( kind=real_long )   :: y
!
!  confirm integer precision
      write (*,*) ' '
      write (*,*) 'Test of integer KIND'
      last_k = -99
      do i = 50,-50,-1
         k = selected_int_kind (i)
         if (k == last_k) cycle
         kind_name = ' undefined'
         if ( k == int_1byte ) kind_name = '1 byte'
         if ( k == int_2byte ) kind_name = '2 byte'
         if ( k == int_4byte ) kind_name = '4 byte'
         if ( k == int_8byte ) kind_name = '8 byte'
         write (*,*) kind_name, ' precision =', i, ' kind =',k
         last_k = k
      end do
!
!  confirm real precision
      write (*,*) ' '
      write (*,*) 'Test of Real precision KIND'
      last_k = -99
      do i = 50,-50,-1
         k = selected_real_kind (i,1)
         if (k == last_k) cycle
         kind_name = ' undefined'
         if ( k == real_float  ) kind_name = '4 byte'
         if ( k == real_double ) kind_name = '8 byte'
         if ( k == real_long   ) kind_name = '10 byte'
         write (*,*) kind_name, ' precision =', i, ' kind =',k
         last_k = k
      end do
!
!  confirm real exponent
      write (*,*) ' '
      write (*,*) 'Test of Real exponent KIND'
      last_k = -99
      do i = 5000,-5000,-1
         k = selected_real_kind (1,i)
         if (k == last_k) cycle
         kind_name = ' undefined'
         if ( k == real_float  ) kind_name = '4 byte'
         if ( k == real_double ) kind_name = '8 byte'
         if ( k == real_long   ) kind_name = '10 byte'
         write (*,*) kind_name, ' exponent =', i, ' kind =',k
         last_k = k
      end do
!
!   test real constants
!
      write (*,*) ' '
      x = 1.0e300_real_double   ; write (*,*) 'x=',x
      y = 1.0e3000_real_long    ; write (*,*) 'y=',y
      x = 1.0d300               ; write (*,*) 'x=',x
!      x = 1.0e300               ; write (*,*) 'x=',x
!      y = 1.0e3000              ; write (*,*) 'y=',y
!
      end


You might like to consider defining your own Fortran 2008 ISO_C_BINDING module, as this provides some standardisation to naming kinds.
We have to suffer because Fortran 90 did not recommend that KIND = number_of_bytes. You can try to be too smart !!
I'd like to know the Fortran 90+ implementations where this could not have been done. Were there any 60-bit Cyber computers still around in 1990 ?

John
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 8254
Location: Salford, UK

PostPosted: Fri Jun 14, 2013 6:57 am    Post subject: Reply with quote

x = 1d400 fails but x = 1e400_3 is OK.
Back to top
View user's profile Send private message AIM Address
DanRRight



Joined: 10 Mar 2008
Posts: 2937
Location: South Pole, Antarctica

PostPosted: Fri Jun 14, 2013 12:54 pm    Post subject: Reply with quote

Thanks John and Paul. So

if(aa.gt.2e-4000_3) write(*,*) 'something'

works but

if(aa.gt.2d-4000_3) write(*,*) 'something'

DOES NOT work!? THAT....that...that's TOTALLY counterintuitive!

And inconvenient. When you program you adjust the value of constant and use E till 10^37, then you use D till 10^309 and then again E??? Inconvenient, confusing, counterintuitive. That will end up with the loss of the whole day for any programmer in future. Or more, because i have got this forum and the pros here, others may lose much more than that. Is this how Standard precludes to do that? If these letter serve as a switch for different implementations of the intrinsic functions when you change precision then for extended precision Standard should allow all three different letters E (for "exponent'), D(from 'Double precision') and, say, X for "extended precision'! Or at least compiler should give the diagnostics and recommendation (giving recommendation would be next good thing for future Fortran compilers)
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 8254
Location: Salford, UK

PostPosted: Fri Jun 14, 2013 3:10 pm    Post subject: Reply with quote

I guess that the D is for double precision so in FTN95 D is equivalent to E with _2 as the KIND.
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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