dlamch.f.html

来自「famous linear algebra library (LAPACK) p」· HTML 代码 · 共 877 行 · 第 1/5 页

HTML
877
字号
</span><span class="comment">*</span><span class="comment">  Arguments
</span><span class="comment">*</span><span class="comment">  =========
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">  BETA    (output) INTEGER
</span><span class="comment">*</span><span class="comment">          The base of the machine.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">  T       (output) INTEGER
</span><span class="comment">*</span><span class="comment">          The number of ( BETA ) digits in the mantissa.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">  RND     (output) LOGICAL
</span><span class="comment">*</span><span class="comment">          Specifies whether proper rounding  ( RND = .TRUE. )  or
</span><span class="comment">*</span><span class="comment">          chopping  ( RND = .FALSE. )  occurs in addition. This may not
</span><span class="comment">*</span><span class="comment">          be a reliable guide to the way in which the machine performs
</span><span class="comment">*</span><span class="comment">          its arithmetic.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">  EPS     (output) DOUBLE PRECISION
</span><span class="comment">*</span><span class="comment">          The smallest positive number such that
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">             fl( 1.0 - EPS ) .LT. 1.0,
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">          where fl denotes the computed value.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">  EMIN    (output) INTEGER
</span><span class="comment">*</span><span class="comment">          The minimum exponent before (gradual) underflow occurs.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">  RMIN    (output) DOUBLE PRECISION
</span><span class="comment">*</span><span class="comment">          The smallest normalized number for the machine, given by
</span><span class="comment">*</span><span class="comment">          BASE**( EMIN - 1 ), where  BASE  is the floating point value
</span><span class="comment">*</span><span class="comment">          of BETA.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">  EMAX    (output) INTEGER
</span><span class="comment">*</span><span class="comment">          The maximum exponent before overflow occurs.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">  RMAX    (output) DOUBLE PRECISION
</span><span class="comment">*</span><span class="comment">          The largest positive number for the machine, given by
</span><span class="comment">*</span><span class="comment">          BASE**EMAX * ( 1 - EPS ), where  BASE  is the floating point
</span><span class="comment">*</span><span class="comment">          value of BETA.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">  Further Details
</span><span class="comment">*</span><span class="comment">  ===============
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">  The computation of  EPS  is based on a routine PARANOIA by
</span><span class="comment">*</span><span class="comment">  W. Kahan of the University of California at Berkeley.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> =====================================================================
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">     .. Local Scalars ..
</span>      LOGICAL            FIRST, IEEE, IWARN, LIEEE1, LRND
      INTEGER            GNMIN, GPMIN, I, LBETA, LEMAX, LEMIN, LT,
     $                   NGNMIN, NGPMIN
      DOUBLE PRECISION   A, B, C, HALF, LEPS, LRMAX, LRMIN, ONE, RBASE,
     $                   SIXTH, SMALL, THIRD, TWO, ZERO
<span class="comment">*</span><span class="comment">     ..
</span><span class="comment">*</span><span class="comment">     .. External Functions ..
</span>      DOUBLE PRECISION   <a name="DLAMC3.388"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</a>
      EXTERNAL           <a name="DLAMC3.389"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</a>
<span class="comment">*</span><span class="comment">     ..
</span><span class="comment">*</span><span class="comment">     .. External Subroutines ..
</span>      EXTERNAL           <a name="DLAMC1.392"></a><a href="dlamch.f.html#DLAMC1.130">DLAMC1</a>, <a name="DLAMC4.392"></a><a href="dlamch.f.html#DLAMC4.612">DLAMC4</a>, <a name="DLAMC5.392"></a><a href="dlamch.f.html#DLAMC5.695">DLAMC5</a>
<span class="comment">*</span><span class="comment">     ..
</span><span class="comment">*</span><span class="comment">     .. Intrinsic Functions ..
</span>      INTRINSIC          ABS, MAX, MIN
<span class="comment">*</span><span class="comment">     ..
</span><span class="comment">*</span><span class="comment">     .. Save statement ..
</span>      SAVE               FIRST, IWARN, LBETA, LEMAX, LEMIN, LEPS, LRMAX,
     $                   LRMIN, LT
<span class="comment">*</span><span class="comment">     ..
</span><span class="comment">*</span><span class="comment">     .. Data statements ..
</span>      DATA               FIRST / .TRUE. / , IWARN / .FALSE. /
<span class="comment">*</span><span class="comment">     ..
</span><span class="comment">*</span><span class="comment">     .. Executable Statements ..
</span><span class="comment">*</span><span class="comment">
</span>      IF( FIRST ) THEN
         ZERO = 0
         ONE = 1
         TWO = 2
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">        LBETA, LT, LRND, LEPS, LEMIN and LRMIN  are the local values of
</span><span class="comment">*</span><span class="comment">        BETA, T, RND, EPS, EMIN and RMIN.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">        Throughout this routine  we use the function  <a name="DLAMC3.414"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</a>  to ensure
</span><span class="comment">*</span><span class="comment">        that relevant values are stored  and not held in registers,  or
</span><span class="comment">*</span><span class="comment">        are not affected by optimizers.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">        <a name="DLAMC1.418"></a><a href="dlamch.f.html#DLAMC1.130">DLAMC1</a> returns the parameters  LBETA, LT, LRND and LIEEE1.
</span><span class="comment">*</span><span class="comment">
</span>         CALL <a name="DLAMC1.420"></a><a href="dlamch.f.html#DLAMC1.130">DLAMC1</a>( LBETA, LT, LRND, LIEEE1 )
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">        Start to find EPS.
</span><span class="comment">*</span><span class="comment">
</span>         B = LBETA
         A = B**( -LT )
         LEPS = A
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">        Try some tricks to see whether or not this is the correct  EPS.
</span><span class="comment">*</span><span class="comment">
</span>         B = TWO / 3
         HALF = ONE / 2
         SIXTH = <a name="DLAMC3.432"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</a>( B, -HALF )
         THIRD = <a name="DLAMC3.433"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</a>( SIXTH, SIXTH )
         B = <a name="DLAMC3.434"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</a>( THIRD, -HALF )
         B = <a name="DLAMC3.435"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</a>( B, SIXTH )
         B = ABS( B )
         IF( B.LT.LEPS )
     $      B = LEPS
<span class="comment">*</span><span class="comment">
</span>         LEPS = 1
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">+       WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP
</span>   10    CONTINUE
         IF( ( LEPS.GT.B ) .AND. ( B.GT.ZERO ) ) THEN
            LEPS = B
            C = <a name="DLAMC3.446"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</a>( HALF*LEPS, ( TWO**5 )*( LEPS**2 ) )
            C = <a name="DLAMC3.447"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</a>( HALF, -C )
            B = <a name="DLAMC3.448"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</a>( HALF, C )
            C = <a name="DLAMC3.449"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</a>( HALF, -B )
            B = <a name="DLAMC3.450"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</a>( HALF, C )
            GO TO 10
         END IF
<span class="comment">*</span><span class="comment">+       END WHILE
</span><span class="comment">*</span><span class="comment">
</span>         IF( A.LT.LEPS )
     $      LEPS = A
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">        Computation of EPS complete.
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">        Now find  EMIN.  Let A = + or - 1, and + or - (1 + BASE**(-3)).
</span><span class="comment">*</span><span class="comment">        Keep dividing  A by BETA until (gradual) underflow occurs. This
</span><span class="comment">*</span><span class="comment">        is detected when we cannot recover the previous A.
</span><span class="comment">*</span><span class="comment">
</span>         RBASE = ONE / LBETA
         SMALL = ONE
         DO 20 I = 1, 3
            SMALL = <a name="DLAMC3.467"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</a>( SMALL*RBASE, ZERO )
   20    CONTINUE
         A = <a name="DLAMC3.469"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</a>( ONE, SMALL )
         CALL <a name="DLAMC4.470"></a><a href="dlamch.f.html#DLAMC4.612">DLAMC4</a>( NGPMIN, ONE, LBETA )
         CALL <a name="DLAMC4.471"></a><a href="dlamch.f.html#DLAMC4.612">DLAMC4</a>( NGNMIN, -ONE, LBETA )
         CALL <a name="DLAMC4.472"></a><a href="dlamch.f.html#DLAMC4.612">DLAMC4</a>( GPMIN, A, LBETA )
         CALL <a name="DLAMC4.473"></a><a href="dlamch.f.html#DLAMC4.612">DLAMC4</a>( GNMIN, -A, LBETA )
         IEEE = .FALSE.
<span class="comment">*</span><span class="comment">
</span>         IF( ( NGPMIN.EQ.NGNMIN ) .AND. ( GPMIN.EQ.GNMIN ) ) THEN
            IF( NGPMIN.EQ.GPMIN ) THEN
               LEMIN = NGPMIN
<span class="comment">*</span><span class="comment">            ( Non twos-complement machines, no gradual underflow;
</span><span class="comment">*</span><span class="comment">              e.g.,  VAX )
</span>            ELSE IF( ( GPMIN-NGPMIN ).EQ.3 ) THEN
               LEMIN = NGPMIN - 1 + LT
               IEEE = .TRUE.
<span class="comment">*</span><span class="comment">            ( Non twos-complement machines, with gradual underflow;
</span><span class="comment">*</span><span class="comment">              e.g., IEEE standard followers )
</span>            ELSE
               LEMIN = MIN( NGPMIN, GPMIN )
<span class="comment">*</span><span class="comment">            ( A guess; no known machine )
</span>               IWARN = .TRUE.
            END IF
<span class="comment">*</span><span class="comment">
</span>         ELSE IF( ( NGPMIN.EQ.GPMIN ) .AND. ( NGNMIN.EQ.GNMIN ) ) THEN
            IF( ABS( NGPMIN-NGNMIN ).EQ.1 ) THEN
               LEMIN = MAX( NGPMIN, NGNMIN )
<span class="comment">*</span><span class="comment">            ( Twos-complement machines, no gradual underflow;
</span><span class="comment">*</span><span class="comment">              e.g., CYBER 205 )
</span>            ELSE
               LEMIN = MIN( NGPMIN, NGNMIN )
<span class="comment">*</span><span class="comment">            ( A guess; no known machine )
</span>               IWARN = .TRUE.
            END IF
<span class="comment">*</span><span class="comment">
</span>         ELSE IF( ( ABS( NGPMIN-NGNMIN ).EQ.1 ) .AND.
     $            ( GPMIN.EQ.GNMIN ) ) THEN
            IF( ( GPMIN-MIN( NGPMIN, NGNMIN ) ).EQ.3 ) THEN
               LEMIN = MAX( NGPMIN, NGNMIN ) - 1 + LT
<span class="comment">*</span><span class="comment">            ( Twos-complement machines with gradual underflow;
</span><span class="comment">*</span><span class="comment">              no known machine )
</span>            ELSE

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?