! FUNCTII INTRINSECI Fortran (CVF) - pentru parametrii reprezentarii.
!
! Model = Modelul de reprezentare pentru date reale (notatia stiitifica):
! x = 0; 
! sau:
! x =s * 2^e * mantisa 
!    s =+1/-1
!    emin <= e <= emax
!    mantisa = SUMA[k=1_k=p]( b_k*2(-k) )
!    b_k =0/1; b_1 =1; 
!
!    poztional:  mantisa =0.b_1b_2 ... b_p
!
!* NOTA: Pentru compilare cu CVF:
!* -----------------------------
!* Faceti comentarii instructiunile referitoare la tipul REAL(16)

real(4) x/1.0_4/ 
real(8) xx/1.0_8/, uu
real(16) xxx/1.0_16/, uuu

integer(8) int8
integer(4) int4
integer(2) int2
integer(1) int1


open(1,file='intrinsec-ivf.rez',status='unknown')
!open(1,file='intrinsec.rez',status='unknown')

write(1,*) '1.0_4 : ',1.0
write(1,*) '1.0_8 : ',1.0_8
write(1,*) '1.0_16 : ',1.0_16
write(1,*)

write(1,*) '* FUNCTII INTRINSECI pentru parametrii reprezentarii in model (IVF) *'  ! (CVF)
write(1,*) '---------------------------------------------------------------------'
write(1,*) '* Toate valorile functiilor se refera la:'
write(1,*) '* Reprezentarea argumentului functiei in "Modelul pentru date reale".'
write(1,*)

write(1,*) 'DIGITS = numarul de cifre semnificative binare (pentru tipul de argument):'
write(1,*) 'digits(integer*1)=', digits(int1)
write(1,*) 'digits(integer*2)=', digits(int2)
write(1,*) 'digits(integer*4)=', digits(int4)
write(1,*) 'digits(integer*8)=', digits(int8)
write(1,*)

write(1,*) 'digits(r*4)=', digits(1.0)
write(1,*) 'digits(r*8)=', digits(1.0_8)
write(1,*) 'digits(r*16)=', digits(1.0_16)

write(1,*)

write(1,*) 'EXPONENT = exponentul (pentru argument):'
write(1,*) 'exponent(1.0)=', exponent(1.0)
write(1,*) 'exponent(1.0_8)=', exponent(1.0_8)
write(1,*) 'exponent(1.0_16)=', exponent(1.0_16)

write(1,*)

write(1,*) 'FRACTION: fractia (pentru argument):'
write(1,*) 'fraction(1.0)=', fraction(1.0)
write(1,*) 'fraction(1.0_8)=', fraction(1.0_8)
write(1,*) 'fraction(1.0_16)=', fraction(1.0_16)
write(1,*)

write(1,*) 'EPSILON = cel mai mic pozitiv "EPS" pt. care 1+EPS > 1 :'
write(1,*) 'epsilon(r*4)=',epsilon(1.0)
write(1,*) 'epsilon(r*8)=',epsilon(1.0_8)
write(1,*) 'epsilon(r*16)=',epsilon(1.0_16)

write(1,*)


write(1,*) 'MAXEXPONENT = cel mai mare exponent pozitiv (in model, baza2):'
write(1,*) 'MAXEXPONENT(r*4)=',MAXEXPONENT(1.0)
write(1,*) 'MAXEXPONENT(r*8)=',MAXEXPONENT(1.0_8)
write(1,*) 'MAXEXPONENT(r*16)=',MAXEXPONENT(1.0_16)
write(1,*)

write(1,*) 'MINEXPONENT = cel mai mic exponent negativ (in model, baza2):'
write(1,*) 'MINEXPONENT(r*4)=',MINEXPONENT(1.0)
write(1,*) 'MINEXPONENT(r*8)=',MINEXPONENT(1.0_8)
write(1,*) 'MINEXPONENT(r*16)=',MINEXPONENT(1.0_16)
write(1,*)

write(1,*) 'NEAREST = cel mai apropiat numar in directia "semnului lui s":'
write(1,*) 'nearest(0., +)=', nearest(0., x)
write(1,*) 'nearest(0., -)=', nearest(0., -x)
write(1,*)

write(1, '(a, 1pE15.6)') ' nearest(1., +)=', nearest(1., x)
write(1, '(a, 1pE15.6)') ' nearest(1., -)=', nearest(1., -x)
write(1,*) 'nearest(1., +)-1.0=', nearest(1., x)-1.0
write(1,*) 'nearest(1., -)-1.0=', nearest(1., -x)-1.0

write(1,*)
write(1, '(a, 1pD24.15)') ' nearest(1.D0, +)=', nearest(1.D0, xx)
write(1, '(a, 1pD24.15)') ' nearest(1.D0, -)=', nearest(1.D0, -xx)
write(1,*) 'nearest(1.D0, +) -1.D0 =', nearest(1.D0, xx) -1.D0
write(1,*) 'nearest(1.D0, -) -1.D0 =', nearest(1.D0, -xx) -1.D0

write(1,*)
write(1, '(a, 1pD44.33)') ' nearest(1.Q0, +)=', nearest(1.Q0, xxx)
write(1, '(a, 1pD44.33)') ' nearest(1.Q0, -)=', nearest(1.Q0, -xxx)

write(1,*)
write(1,*) 'HUGE = cel mai mare pozitiv reprezentabil:'
write(1,*) 'huge(r*4)=',huge(1.0)
write(1,*) 'huge(r*8)=',huge(1.0_8)
write(1,*) 'huge(r*16)=',huge(1.0_16)
write(1,*)

write(1,*) 'huge(integer*1)=',huge(int1)
write(1,*) 'huge(integer*2)=',huge(int2)
write(1,*) 'huge(integer*4)=',huge(int4)
write(1,*) 'huge(integer*8)=',huge(int8)
write(1,*)

write(1,*) 'PRECISION = precizia, in numar de cifre semnificative zecimale:'
write(1,*) 'precision(r*4)=',precision(1.0)
write(1,*) 'precision(r*8)=',precision(1.0_8)
write(1,*) 'precision(r*16)=',precision(1.0_16)
write(1,*) 

write(1,*) 'RANGE = rangul exponentului zecimal:'
write(1,*) 'Intreg: Partea intreaga a lui: log10(HUGE(x));' 
write(1,*) 'Real:   Partea intreaga a lui: MIN( log10(HUGE(x)), -log10(TINY(x)) )'

write(1,*) 'range(integer*1)=', range(int1)
write(1,*) 'range(integer*2)=', range(int2)
write(1,*) 'range(integer*4)=', range(int4)
write(1,*) 'range(integer*8)=', range(int8)
write(1,*)

write(1,*) 'range(real*4)=', range(1.0)
write(1,*) 'range(real*8)=', range(1.0_8)
write(1,*) 'range(real*16)=', range(1.0_16)
write(1,*)

write(1,*) 'RRSPACING = inversa spatierii numerelor in vecinatatea lui 1.0:'
write(1,*) 'rrspacing(real*4)=',rrspacing(1.0)
write(1,*) 'rrspacing(real*8)=',rrspacing(1.0_8)
write(1,*) 'rrspacing(real*16)=',rrspacing(1.0_16)
write(1,*)

write(1,*) 'SPACING = spatierea absoluta a numerelor in vecinatatea lui 1.0:'
write(1,*) 'spacing(real*4)=', spacing(1.0)
write(1,*) 'spacing(real*8)=', spacing(1.0_8)
write(1,*) 'spacing(real*16)=', spacing(1.0_16)
write(1,*)

write(1,*) 'TINY = cel mai mic pozitiv reprezentabil:'
write(1,*) 'tiny(r*4)=',tiny(1.0)
write(1,*) 'tiny(r*8)=',tiny(1.0_8)
write(1,*) 'tiny(r*16)=',tiny(1.0_16)
write(1,*)

u =1.+epsilon(1.0)
if(u >1.) then
write(1,*) '1. +EPS(real*4) >1.'
else
write(1,*) '1. +EPS(real*4) =1.'
endif
write(1,*)

uu =1._8 +epsilon(1.0_8)
if( uu>1.) then
write(1,*) '1.0_8 +EPS(real*8) >1.'
else
write(1,*) '1.0_8 +EPS(real*8) =1.'
endif
write(1,*)

uuu =1._16 +epsilon(1.0_16)
if( uu>1.) then
write(1,*) '1.0_16 +EPS(real*16) >1.'
else
write(1,*) '1.0_16 +EPS(real*16) =1.'
endif

write(1,*)
write(1,*) '* END Functii Intrinseci *'

write(*, '(a)') ' Fisier de rezultate: "intrinsec-ivf.rez"'
!write(*, '(a)') ' Fisier de rezultate: "intrinsec.rez"'

END
