C$Procedure DPPREC_1 ( Precision for Double Precision Numbers ) DOUBLE PRECISION FUNCTION DPPREC_1 ( ) C$ Abstract C C Return the smallest power of 2, DPPREC_1, such that C 1 + DPPREC_1 .NE. 1 and 1 - DPPREC_1 .NE. 1 C C$ Required_Reading C C None. C C$ Keywords C C CONSTANTS C MATH C NUMBERS C C$ Declarations C$ Brief_I/O C C VARIABLE I/O DESCRIPTION C -------- --- -------------------------------------------------- C DPPREC_1 O Returns the smallest effective increment to 1. C C$ Detailed_Input C C None. C C$ Detailed_Output C C DPPREC_1 is assigned the smallest power of 2 that can be C added to or subtracted from the double precision C number 1 and yield a result different from 1. C C$ Files C C None. C C$ Exceptions C C None. C C$ Particulars C C This function computes the smallest power of 2, DPPREC_1, for C which C C 1.0D0 + DPPREC_1 .NE. 1.0D0 C 1.0D0 - DPPREC_1 .NE. 1.0D0 C C AND C C ( 1.0D0 + DPPREC_1 ) - 1.0D0 = DPPREC_1 C - ( 1.0D0 - DPPREC_1 ) + 1.0D0 = DPPREC_1 C C The last pair of conditions may seem a bit silly, however, C depending upon how a particular implementation performs round-off C when performing double precision arithmetic, it is possible to C satisfy the first pair of conditions and not satisfy the second C pair. C C$ Examples C C None. C C$ Restrictions C C None. C C$ Literature_References C C None. C C$ Author_and_Institution C C W.L. Taber (JPL) C C$ Version C C Beta Version 1.0.0, 23-JUN-1988 (WLT) C C-& C C Local variables C DOUBLE PRECISION LAST DOUBLE PRECISION INCR DOUBLE PRECISION DECR C C Saved variables C DOUBLE PRECISION EPSILN SAVE EPSILN C C Initial values C DATA EPSILN / 1.0D0 / IF ( EPSILN .NE. 1.0D0 ) THEN C C We've already computed the correct value of DPPREC_1 on a C previous call to this routine. Put the value in and return. C DPPREC_1 = EPSILN ELSE INCR = 2.0D0 DECR = 0.0D0 C C Store the last value of EPSILN, cut EPSILN in half and add and C subtract it from 1 until we get 1 back as a result of the C addition or subtraction. C DO WHILE ( ( INCR .NE. 1.0D0 ) .AND. ( DECR .NE. 1.0D0 ) ) LAST = EPSILN EPSILN = LAST * 0.5D0 INCR = 1.0D0 + EPSILN DECR = 1.0D0 - EPSILN IF ( INCR - 1.0D0 .NE. EPSILN ) THEN INCR = 1 END IF IF ( 1.0D0 - DECR .NE. EPSILN ) THEN DECR = 1 END IF END DO EPSILN = LAST DPPREC_1 = EPSILN END IF RETURN END