```

REAL FUNCTION RATIO( A, B ) 1,2

c        Calculate ratio  A/B  with over- and under-flow protection
c        (thanks to Prof. Jeff Dozier for some suggestions here).
c        Since this routine takes two logs, it is no speed demon,
c        but it is invaluable for comparing results from two runs
c        of a program under development.
c
c        NOTE:  In Fortran90, built-in functions TINY and HUGE
c               can replace the R1MACH calls.
c ---------------------------------------------------------------

c     .. Scalar Arguments ..

REAL      A, B
c     ..
c     .. Local Scalars ..

LOGICAL   PASS1
REAL      ABSA, ABSB, HUGE, POWA, POWB, POWMAX, POWMIN, TINY
c     ..
c     .. External Functions ..

REAL      R1MACH
EXTERNAL  R1MACH
c     ..
c     .. Intrinsic Functions ..

INTRINSIC ABS, LOG10, SIGN
c     ..
SAVE      PASS1, TINY, HUGE, POWMAX, POWMIN
DATA      PASS1 / .TRUE. /
c     ..

IF( PASS1 ) THEN

TINY   = R1MACH( 1 )
HUGE   = R1MACH( 2 )
POWMAX = LOG10( HUGE )
POWMIN = LOG10( TINY )
PASS1  = .FALSE.

END IF

IF( A.EQ.0.0 ) THEN

IF( B.EQ.0.0 ) THEN

RATIO  = 1.0

ELSE

RATIO  = 0.0

END IF

ELSE IF( B.EQ.0.0 ) THEN

RATIO  = SIGN( HUGE, A )

ELSE

ABSA   = ABS( A )
ABSB   = ABS( B )
POWA   = LOG10( ABSA )
POWB   = LOG10( ABSB )

IF( ABSA.LT.TINY .AND. ABSB.LT.TINY ) THEN

RATIO  = 1.0

ELSE IF( POWA - POWB.GE.POWMAX ) THEN

RATIO  = HUGE

ELSE IF( POWA - POWB.LE.POWMIN ) THEN

RATIO  = TINY

ELSE

RATIO  = ABSA / ABSB

END IF
c                      ** DONT use old trick of determining sign
c                      ** from A*B because A*B may (over/under)flow

IF(     &       ( A.LT.0.0 .AND. B.GT.0.0 ) ) RATIO = -RATIO

END IF

RETURN
END
```