! The "Unit in the Last Place"
! Often: the smallest number, that added to x produces a FP number >x. 
! Double precision.
! CVF: use dflib
Program ULP_x
use ifcore

implicit real(8) (a-h, o-z)

character(260) fname, fname1, w*1
integer width
logical pressed/.false./


99 format(71(1H-))

print '(a, \)', 'Input file name (NO extension): '
read '(a)', fname
fname1 =trim(fname)//'.rez'

open (1, file= fname1, status ='unknown')
write(1, '(a)') ' Model: x =s*2^exponent*fractie'
write(1, '(a)') ' exponent =exponent(x); fractie =fraction(x);'

write(1, '(/,a,/a)') ' x: real(8)',  ' ULP(x) =2**(exponent(x) -53)'
write(1,*)
write(1,*) 'x1 =x +ULP(x)'
write(1,*) 'x2 =x +ULP(x)/2.'
write(1,*) '[x3 =x +ULP(x)/4.]'

iwb =32
iwe =8

100 print '(a\)',' Input xStart, xEnd (0=stop), xStep: '
read*, xStart, xEnd, xStep
if(xEND ==0.) STOP

write(1,*)
ULP_ant =0.

DO x =xStart, xEnd, xStep

ULPx =ULP(x)	! ULP(x) =smallest add to 'x'
x1 =x +ULPx
x2 =x +ULPx/2.
x3 =x +ulpx/4.


if(ULPx /=ULP_ant) then
write(1, 99)
write(1, '(t6,a, t28,a, t50,a, t62,a)') ' x', 'fractie(x)', 'exponent(x)', ' ULP(x)'
endif

iwe =width(exponent(x))
write(1, '(/,a, 1pD22.15, t27,1pg23.16, t50,I<iwe>, t62,1pd22.15)')  'x: ', x, fraction(x), exponent(x), ULPx;

write(1,*)
write(1, '(a, 1pd22.15, t27,1pg23.16, \)') 'x1:', x1, fraction(x1)
if(x1 ==x) then
write(1, '(a, :, t14,a,1pd22.15)') 'x1 =x'
elseif(x1 >x) then
write(1, '(a, :, t14,a,1pd22.15)') 'x1 >x', 'x1-x = ', x1-x

else
write(1,*) 'x1 <x',';	x1-x =',x1-x
endif

write(1, '(a, 1pd22.15, t27,1pg23.16, \)') 'x2:', x2, fraction(x2)
if(x2 ==x) then
write(1, '(a, t14,a, :, 1pd22.15)') 'x2 =x'
elseif(x2 >x) then
write(1, '(a, t14,a,1pd22.15)') 'x2 >x', 'x2-x = ', x2-x

else
write(1,*) 'x2 <x',';	x2-x =', x2-x
endif

IF(x2>x) THEN
write(1,*)
write(1, '(a, t5,1pd22.15, t27,1pg23.16, \)') 'x3:', x3, fraction(x3)

    if(x3 >x) then
    write(1, '(a, t14,a, :, 1pg22.15)') 'x3 >x', 'x3-x = ', x3-x

    elseif(x3==x) then
    write(1, '(a, t14,a, :, 1pg22.15)') 'x3 =x'
    endif
ENDIF

ULP_ant =ULPx
ENDDO


print '(/a\)', ' Another Range? (Y,y / char):'
read '(a1)', w
if(w =='Y' .or. w=='y') then
goto 100
else
write(1,99)
print '(/, a, a)', 'Fisier de rezultate: ', trim(fname1)
endif

write(*, '(/,a)') 'Apasa orice tasta'
DO WHILE (.NOT. pressed)   
pressed = PEEKCHARQQ ( )
END DO

END

