Re: Precision question



You might also like to look at a couple of simple
programs working with kind types.

The first

PROGRAM ch0806
!
! Examples of the use of the kind
! function and the numeric inquiry functions
!
! Integer arithmetic
!
! 32 bits is a common word size,
! and this leads quite cleanly
! to the following
! 8 bit integers
! -128 to 127 10**2
! 16 bit integers
! -32768 to 32767 10**4
! 32 bit integers
! -2147483648 to 2147483647 10**9
!
! 64 bit integers are increasingly available.
! This leads to
! -9223372036854775808 to
! 9223372036854775807 10**19
!
! You may need to comment out some of the following
! depending on the hardware platform and compiler
! that you use.

INTEGER :: I
INTEGER ( SELECTED_INT_KIND( 2)) :: I1
INTEGER ( SELECTED_INT_KIND( 4)) :: I2
INTEGER ( SELECTED_INT_KIND( 9)) :: I3
INTEGER ( SELECTED_INT_KIND(10)) :: I4


! Real arithmetic
!
! 32 and 64 bit reals are normally available.
!
! 32 bit reals 8 bit exponent, 24 bit mantissa
!
! 64 bit reals 11 bit exponent 53 bit mantissa
!
REAL :: R
REAL ( SELECTED_REAL_KIND( 6, 37)) :: R1
REAL ( SELECTED_REAL_KIND(15,307)) :: R2
REAL ( SELECTED_REAL_KIND(15,310)) :: R3

PRINT *,' '
PRINT *,' Integer values'
PRINT *,' Kind Huge'
PRINT *,' '
PRINT *,' ',KIND(I ),' ',HUGE(I )
PRINT *,' '
PRINT *,' ',KIND(I1 ),' ',HUGE(I1 )
PRINT *,' ',KIND(I2 ),' ',HUGE(I2 )
PRINT *,' ',KIND(I3 ),' ',HUGE(I3 )
PRINT *,' ',KIND(I4 ),' ',HUGE(I4 )

PRINT *,' '
PRINT *,' Real values'
PRINT *,' Kind Huge ',&
'Precision epsilon'
PRINT *,' '
PRINT *,' ',KIND(R ),' ',HUGE(R ),&
' ',PRECISION(R),' ',EPSILON(R)
PRINT *,' '
PRINT *,' ',KIND(R1 ),' ',HUGE(R1 ),&
' ',PRECISION(R1),' ',EPSILON(R1)
PRINT *,' ',KIND(R2 ),' ',HUGE(R2 ),&
' ',PRECISION(R2),' ',EPSILON(R2)
PRINT *,' ',KIND(R3 ),' ',HUGE(R3 ),&
' ',PRECISION(R3),' ',EPSILON(R3)
END PROGRAM ch0806

tests out what is available for a compiler.

The next

module precision_definition
implicit none
integer , parameter :: long=selected_real_kind(15,307)
end module precision_definition

module maths_constants
use precision_definition
implicit none
real (long) , parameter :: c = 299792458.0_long
! units m s-1
real (long) , parameter :: &
e = 2.71828182845904523_long
real (long) , parameter :: g = 9.812420_long
! 9.780 356 m s-2 at sea level on the equator
! 9.812 420 m s-2 at sea level in London
! 9.832 079 m s-2 at sea level at the poles
real (long) , parameter :: &
pi = 3.14159265358979323_long
end module maths_constants

PROGRAM ch2401
USE Precision_definition
IMPLICIT NONE
INTERFACE
SUBROUTINE Sub1(Radius,Area,Circum)
USE Precision_definition
IMPLICIT NONE
REAL(Long),INTENT(IN)::Radius
REAL(Long),INTENT(OUT)::Area,Circum
END SUBROUTINE Sub1
END INTERFACE
REAL(Long)::R,A,C
INTEGER ::I
DO I=1,10
PRINT*,'Radius?'
READ*,R
CALL Sub1(R,A,C)
PRINT *,' For radius = ',R
PRINT *,' Area = ',A
PRINT *,' Circumference = ',C
END DO
END PROGRAM ch2401

SUBROUTINE Sub1(Radius,Area,Circum)
USE Precision_definition
use maths_constants
IMPLICIT NONE
REAL(Long),INTENT(IN)::Radius
REAL(Long),INTENT(OUT)::Area,Circum
Area=Pi*Radius*Radius
Circum=2.0_Long*Pi*Radius
END SUBROUTINE Sub1

shows you how to use a module
to set up the precision you are interested
in.

note that literal numeric constants as in
the assignment statement

Circum=2.0_Long*Pi*Radius

^^^^^^

and the folowing

real (long) , parameter :: c = 299792458.0_long

^^^^^^

have the kind type as part of the number.

hope this helps.


Led wrote:
I'm reading FORTRAN 90/95 explained, 2nd ed., by Metcalf & Reid.

If I understood, in FORTRAN95, the intrinsic functions should be
computetd with the precision of their first argument, so there is no
need
for using, e.g., COS, DCOS, QCOS depending on the case. Hence,
using COS(X) should give the correct answer according to the kind of X.

The same should be true for more elementary function like X+1E0 that
should give the same result as X+1D0. Right?

I made the following test:

!!!!!!!!!!!!!!!!
program test

implicit none
real*16 :: x

x=1e-7
write(*,*) cos(x) - .99999999999999500000000000000416666666666667e0

x=1d-7
write(*,*) cos(x) - .99999999999999500000000000000416666666666667d0

x=1q-7
write(*,*) cos(x) - .99999999999999500000000000000416666666666667e0

x=1q-7
write(*,*) cos(x) - .99999999999999500000000000000416666666666667d0

x=1q-7
write(*,*) cos(x) - .99999999999999500000000000000416666666666667q0


end program
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

and only the last one give the expected results (that is 0). Why?

Did I misunderstood the standard?

If x is declared as quadruple precision, then the command x=1e-7
should affect x with the quadruple precision format of 1e-7, no?

Then cos(x) should be quadruple precision too.
Then in cos(x)-0.999...., 0.999... should be converted to a quadruple
too, no?

I thought that the problem is perhaps due to the fact that quadruple
precision is not standard. Then, I re-did the test with the declaration

real*8 :: x instead. Then, only the second and fourth results are
correct.

So here is my main question:
What is exactly standard here?

Many thanks for your enlightments.
Led

PS: My compiler is:
Intel(R) Fortran Compiler Integration for Microsoft Visual Studio .NET
2003,
Version 9.1.3192.2003, Copyright (C) 2002-2006 Intel Corporation

.



Relevant Pages

  • Re: Rounding off double precision
    ... -|support quad precision, there is no statement that will work. ... Public domain 2004 by James Van Buskirk ... print *, "dp reals are of kind number", number ...
    (comp.lang.fortran)
  • Re: internal procedure as an actual argument
    ... But it should be clear that I did not create an integration method ... implicit none ... subroutine integration_new ... double precision function new_fonc ...
    (comp.lang.fortran)
  • Re: Unexpected 15 digits precision from "REAL"
    ... My question is "What was the default precision of ... Compilations of the programs today, ... way that the digits to the left of the string of trailing zeroes are ... I am not sure what the characteristics are for reals other than those ...
    (comp.lang.fortran)
  • Re: internal procedure as an actual argument
    ... included in a OO integration class. ... implicit none ... subroutine integration_new ... double precision function new_fonc ...
    (comp.lang.fortran)
  • Re: internal procedure as an actual argument
    ... included in a OO integration class. ... implicit none ... subroutine integration_new ... double precision function new_fonc ...
    (comp.lang.fortran)