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