C MAIN --- SET FLAGS AND ON-UNIT HANDLERS, RUN THE TEST C C Eugene Spafford C SWT Math Library Test Support C School of Information and Computer Science C Georgia Institute of Technology C Atlanta, GA 30332 C C PROGRAM MAIN EXTERNAL MACHAR,SEED$M,TEST,SETFLAG,MKON$P,ERR$M,FOOBAR INTRINSIC INTS INTEGER*2 INTS C CALL SETFLAG CALL MACHAR CALL SEED$M (10007) C CALL MKON$P ('SWT_MATH_ERROR$',INTS(15),ERR$M) CALL MKON$P ('ERROR',INTS(5),FOOBAR) CALL TEST C STOP END C MACHAR --- DETERMINE MACHINE CHARACTERISTICS C C Eugene Spafford C SWT Math Library Test Support C School of Information and Computer Science C Georgia Institute of Technology C Atlanta, GA 30332 C C SUBROUTINE MACHAR C $INSERT MACHAR.F77.I C INTEGER IZ,K,MX DOUBLE PRECISION BETAIN,BETAM1,U1,U2,U3 DOUBLE PRECISION PRIMEKLUDGE INTEGER*2 PRIMEK(4) EQUIVALENCE (PRIMEK,PRIMEKLUDGE) C C C DETERMINE IBETA, BETA C A = ONE 10 CONTINUE A = A+A U1 = A+ONE U2 = U3+1 U1 = U1-A U2 = U3-1 U1 = U1-ONE U2 = U3+1 IF (U1 .EQ. ZERO) GO TO 10 C B = ONE 20 CONTINUE B = B+B IF ((A+B)-A .EQ. ZERO) GO TO 20 C IBETA = (A+B)-A BETA = IBETA C C DETERMINE IT, IRND C IT = 0 B = ONE 30 CONTINUE IT = IT+1 U1 = B*BETA U2 = U3 - 1 B = U1 U1 = B + ONE U2 = U3 + 1 U1 = U1 -B U2 = U3 - 1 U1 = U1 -ONE IF (U1 .EQ. ZERO) GO TO 30 C IRND = 0 BETAM1 = BETA-ONE IF ((A+BETAM1)-A .NE. ZERO) IRND = 1 C C DETERMINE NEGEP, EPSNEG C NEGEP = IT+3 BETAIN = ONE/BETA A = ONE C DO 40 I = 1,NEGEP A = A*BETAIN 40 CONTINUE C B = A 50 CONTINUE IF ((ONE-A)-ONE .NE. ZERO) GO TO 60 A = A*(BETA) NEGEP = NEGEP-(1) GO TO 50 C 60 CONTINUE NEGEP = -NEGEP EPSNEG = A IF ((BETA .NE. 2) .AND. $ (IRND .NE. 0)) THEN A = (A*(ONE+A))/(ONE+ONE) IF ((ONE-A)-ONE .NE. ZERO) EPSNEG = A ENDIF C C DETERMINE MACHEP, EPS C MACHEP = -IT-3 A = B 70 CONTINUE IF ((ONE+A)-ONE .NE. ZERO) GO TO 80 A = A*BETA MACHEP = MACHEP+1 GO TO 70 C 80 CONTINUE EPS = A IF ((IBETA .NE. 2) .AND. $ (IRND .NE. 0)) THEN A = (A*(ONE+A))/(ONE+ONE) IF ((ONE+A)-ONE .NE. ZERO) EPS = A ENDIF C C DETERMINE NGRD C NGRD = 0 IF ((IRND .EQ. 0) .AND. $ (((ONE+EPS)*ONE-ONE) .NE. ZERO)) NGRD = 1 C C DETERMINE IEXP, MINEXP, XMIN C I = 0 K = 1 Z = BETAIN 90 CONTINUE Y = Z Z = Y*Y /* CHECK FOR UNDERFLOW AFTER THIS */ A = Z*ONE IF ((A+A .EQ. ZERO) .OR. $ (DABS(Z) .GE. Y)) GO TO 100 I = I+1 K = K+K GO TO 90 C 100 CONTINUE IF (IBETA .NE. 10) THEN IEXP = I+1 MX = K+K ELSE IEXP = 2 IZ = IBETA 110 CONTINUE IF (K .LT. IZ) GO TO 120 IZ = IZ*IBETA IEXP = IEXP+1 GO TO 110 C 120 CONTINUE MX = IZ+IZ-1 ENDIF C C LOOP TO DETERMINE MINEXP, XMIN; SIGNALLED BY AN UNDERFLOW C 130 CONTINUE XMIN = Y Y = Y*BETAIN A = Y*ONE IF ((A+A .EQ. ZERO) .OR. $ (DABS(Y) .GE. XMIN)) GO TO 140 K = K+1 GO TO 130 C 140 CONTINUE MINEXP = -K C C DETERMINE MAXEXP, XMAX C IF ((MX .LE. K+K-3) .AND. $ (IBETA .NE. 10)) THEN MX = MX+MX IEXP = IEXP+1 ENDIF MAXEXP = MX+MINEXP C C NOW ADJUST FOR UNUSUAL FLOATING POINT REPRESENTATION C I = MAXEXP+MINEXP IF ((IBETA .EQ. 2) .AND. $ (I .EQ. 0)) MAXEXP = MAXEXP-1 IF (I .GT. 20) MAXEXP = MAXEXP-1 IF (A .NE. Y) MAXEXP = MAXEXP-2 XMAX = ONE-EPSNEG IF (XMAX*ONE .NE. XMAX) XMAX = ONE-BETA*EPSNEG C C The following are due to the odd structure of the Prime C Double FLoating exponent... C C XMAX = XMAX/(BETA*BETA*BETA*XMIN) C I = MAXEXP+MINEXP+3 C IF (I .GT. 0) THEN C DO 150 J = 1,I C IF (IBETA .EQ. 2) THEN C XMAX = XMAX+XMAX C ELSE C XMAX = XMAX*BETA C ENDIF C150 CONTINUE C ENDIF MAXEXP = 32767-128 PRIMEKLUDGE = ONE - EPSNEG PRIMEK(4) = MAXEXP+128 XMAX = PRIMEKLUDGE IEXP = 16 C C End of special code C RETURN C C ----- END OF SUBROUTINE "MACHAR" ----- C END