⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xp_module.f90

📁 任意多精度计算模块xp_module 很好用的
💻 F90
📖 第 1 页 / 共 5 页
字号:
             NDIG = NSTACK(J)             CALL FMSIN(MB,M06)             CALL FMMPY(M06,M06,M03)             CALL FMI2M(1,M04)             CALL FMSUB(M04,M03,M03)             CALL FMSQRT(M03,M04)             CALL FMDIV(M06,M04,M04)             CALL FMSUB(M04,M05,M04)             CALL FMMPY(M03,M04,M04)             CALL FMSUB(MB,M04,MB)  120     CONTINUE      ENDIF!             If MA.GE.1 use pi/2 - ATAN(1/MA)  130 IF (MA1.GE.1) THEN          CALL FMDIVI(MPISAV,2,M06)          CALL FMSUB(M06,MB,MB)      ENDIF!             Convert to degrees if necessary, round and return.      KRAD = KRSAVE      IF (KRAD.EQ.0) THEN          CALL FMMPYI(MB,180,MB)          CALL FMDIV(MB,MPISAV,MB)      ENDIF      IF (MA2.LT.0) MB(2) = -MB(2)      IF (KFLAG.EQ.1) KFLAG = 0      KWARN = KWSV      CALL FMEXIT(MB,MB,NDSAVE,MXSAVE,KASAVE,KOVUN)END SUBROUTINESUBROUTINE FMATN2(MA,MB,MC)!  MC = ATAN2(MA,MB)!  MC is returned as the angle between -pi and pi (or -180 and 180 if!  degree mode is selected) for which TAN(MC) = MA/MB.  MC is an angle!  for the point (MB,MA) in polar coordinates.      DIMENSION MA(LUNPCK),MB(LUNPCK),MC(LUNPCK)      CALL FMENTR(6,MA,MB,2,MC,KRESLT,NDSAVE,MXSAVE,KASAVE,KOVUN)      IF (KRESLT.NE.0) RETURN      KARGSW = 0      KWSV = KWARN      KWARN = 0      CALL FMEQU(MA,M01,NDSAVE,NDIG)      CALL FMEQU(MB,M02,NDSAVE,NDIG)!             Check for special cases.      IF (MA(1).EQ.KUNKNO .OR. MB(1).EQ.KUNKNO .OR.  &         (MA(2).EQ.0 .AND. MB(2).EQ.0)) THEN          CALL FMIM(0,MC)          MC(1) = KUNKNO          MC(2) = 1          KFLAG = -4          GO TO 110      ENDIF      IF (MB(2).EQ.0 .AND. MA(2).GT.0) THEN          IF (KRAD.EQ.0) THEN              CALL FMI2M(90,MC)          ELSE              CALL FMPI(MC)              CALL FMDIVI(MC,2,MC)          ENDIF          GO TO 110      ENDIF      IF (MB(2).EQ.0 .AND. MA(2).LT.0) THEN          IF (KRAD.EQ.0) THEN              CALL FMI2M(-90,MC)          ELSE              CALL FMPI(MC)              CALL FMDIVI(MC,-2,MC)          ENDIF          GO TO 110      ENDIF      IF (MA(1).EQ.KEXPOV .AND. MB(1).LT.MXSAVE-NDIG-2) THEN          IF (KRAD.EQ.0) THEN              CALL FMI2M(90,MC)          ELSE              CALL FMPI(MC)              CALL FMDIVI(MC,2,MC)          ENDIF          IF (M01(2).LT.0) MC(2) = -MC(2)          GO TO 110      ENDIF      IF (MA(1).EQ.KEXPUN .AND. (-MB(1)).LT.MXSAVE-NDIG-2 .AND.  &                                 MB(2).LT.0) THEN          IF (KRAD.EQ.0) THEN              CALL FMI2M(180,MC)          ELSE              CALL FMPI(MC)          ENDIF          IF (M01(2).LT.0) MC(2) = -MC(2)          GO TO 110      ENDIF      IF (MB(1).EQ.KEXPOV .AND. MA(1).LT.MXSAVE-NDIG-2 .AND.  &                                MB(2).LT.0) THEN          IF (KRAD.EQ.0) THEN              CALL FMI2M(180,MC)          ELSE              CALL FMPI(MC)          ENDIF          IF (M01(2).LT.0) MC(2) = -MC(2)          GO TO 110      ENDIF      IF (MB(1).EQ.KEXPUN .AND. MA(2).EQ.0) THEN          IF (MB(2).LT.0) THEN              IF (KRAD.EQ.0) THEN                  CALL FMI2M(180,MC)              ELSE                  CALL FMPI(MC)              ENDIF          ELSE              CALL FMI2M(0,MC)          ENDIF          GO TO 110      ENDIF      IF (MB(1).EQ.KEXPUN .AND. (-MA(1)).LT.MXSAVE-NDIG-2) THEN          IF (KRAD.EQ.0) THEN              CALL FMI2M(90,MC)          ELSE              CALL FMPI(MC)              CALL FMDIVI(MC,2,MC)          ENDIF          IF (M01(2).LT.0) MC(2) = -MC(2)          GO TO 110      ENDIF!             Determine the quadrant for the result, then use FMATAN.      IF (MA(2).GE.0 .AND. MB(2).GT.0) JQUAD = 1      IF (MA(2).GE.0 .AND. MB(2).LT.0) JQUAD = 2      IF (MA(2).LT.0 .AND. MB(2).LT.0) JQUAD = 3      IF (MA(2).LT.0 .AND. MB(2).GT.0) JQUAD = 4      CALL FMDIV(M01,M02,MC)      MC(2) = ABS(MC(2))      CALL FMATAN(MC,MC)      IF (JQUAD.EQ.2 .OR. JQUAD.EQ.3) THEN          IF (KRAD.EQ.0) THEN              CALL FMI2M(180,M05)              CALL FMSUB(M05,MC,MC)          ELSE              CALL FMPI(M05)              CALL FMSUB(M05,MC,MC)          ENDIF      ENDIF      IF ((JQUAD.EQ.3 .OR. JQUAD.EQ.4) .AND. MC(1).NE.KUNKNO)  &          MC(2) = -MC(2)!             Round the result and return.  110 IF (KFLAG.EQ.1) KFLAG = 0      KWARN = KWSV      CALL FMEXIT(MC,MC,NDSAVE,MXSAVE,KASAVE,KOVUN)END SUBROUTINESUBROUTINE FMBIG(MA)!     MA = The biggest representable FM number using the current base!          and precision.!          The smallest positive number is then 1.0/MA.!          Because of rounding, 1.0/(1.0/MA) will then overflow.      DIMENSION MA(LUNPCK)      NCALL = NCALL + 1      KSTACK(NCALL) = 7      KFLAG = 0      N1 = NDIG + 1      DO 110 J = 2, N1         MA(J) = JBASE - 1  110 CONTINUE      MA(1) = MXEXP + 1      IF (NTRACE.NE.0) CALL FMNTR(1,MA,MA,1)      NCALL = NCALL - 1END SUBROUTINESUBROUTINE FMCAT(MA,NCAT)!  NCAT is returned as the category of MA.  This is used by the various!  arithmetic routines to handle special cases such as:!  'number greater than 1' + 'underflowed result' is the first argument,!  'overflowed result' / 'overflowed result' is 'unknown'.!  NCAT       range!   1.         -OV                OV stands for overflowed results.!   2.   (-OV   , -OVTH)             ( MA(1) .GE. MAXEXP+2 )!   3.   (-OVTH ,    -1)!   4.         -1                 OVTH stands for a representable!   5.   (-1    , -UNTH)               number near the overflow!   6.   (-UNTH ,   -UN)               threshold.!   7.         -UN                     ( MA(1) .GE. MAXEXP-NDIG+1 )!   8.          0!   9.         +UN                UN stands for underflowed results.!  10.   (+UN   , +UNTH)             ( MA(1) .LE. -MAXEXP-1 )!  11.   (+UNTH ,    +1)!  12.         +1                 UNTH stands for a representable!  13.   (+1    , +OVTH)               number near the underflow!  14.   (+OVTH ,   +OV)               threshold.!  15.         +OV                     ( MA(1) .LE. -MAXEXP+NDIG-1 )!  16.       UNKNOWN      DIMENSION MA(LUNPCK)!             Check for special symbols.      NCAT = 16      IF (MA(1).EQ.KUNKNO) RETURN      IF (MA(1).EQ.KEXPOV) THEN          NCAT = 15          IF (MA(2).LT.0) NCAT = 1          RETURN      ENDIF      IF (MA(1).EQ.KEXPUN) THEN          NCAT = 9          IF (MA(2).LT.0) NCAT = 7          RETURN      ENDIF      IF (MA(2).EQ.0) THEN          NCAT = 8          RETURN      ENDIF!             Check for +1 or -1.      MA2 = ABS(MA(2))      IF (MA(1).EQ.1 .AND. MA2.EQ.1) THEN          NLAST = NDIG + 1          IF (NLAST.GE.3) THEN              DO 110 J = 3, NLAST                 IF (MA(J).NE.0) GO TO 120  110         CONTINUE          ENDIF          NCAT = 12          IF (MA(2).LT.0) NCAT = 4          RETURN      ENDIF  120 IF (MA(1).GE.MXEXP-NDIG+1) THEN          NCAT = 14          IF (MA(2).LT.0) NCAT = 2          RETURN      ENDIF      IF (MA(1).GE.1) THEN          NCAT = 13          IF (MA(2).LT.0) NCAT = 3          RETURN      ENDIF      IF (MA(1).GE.-MXEXP+NDIG) THEN          NCAT = 11          IF (MA(2).LT.0) NCAT = 5          RETURN      ENDIF      IF (MA(1).GE.-MXEXP) THEN          NCAT = 10          IF (MA(2).LT.0) NCAT = 6          RETURN      ENDIFEND SUBROUTINEFUNCTION FMCOMP(MA,LREL,MB)   LOGICAL FMCOMP   DIMENSION MA(LUNPCK),MB(LUNPCK)   CHARACTER *2 LREL!  Logical comparison of FM numbers MA and MB.!  LREL is a CHARACTER *2 description of the comparison to be done:!  LREL = 'EQ' returns FMCOMP = .TRUE. if MA.EQ.MB!       = 'NE', 'GE', 'GT', 'LE', 'LT' also work like a logical IF.!  For comparisons involving 'UNKNOWN' or two identical special symbols!  such as +OVERFLOW,'EQ',+OVERFLOW FMCOMP is returned FALSE and a!  KFLAG = -4 error condition is returned.      NCALL = NCALL + 1      KSTACK(NCALL) = 8      IF (NCALL.LE.LVLTRC .AND. ABS(NTRACE).GE.2) THEN          WRITE (KW,110)  110     FORMAT(' INPUT TO FMCOMP')          IF (NTRACE.GT.0) THEN              CALL FMPRNT(MA)              WRITE (KW,120) LREL  120         FORMAT(7X,'.',A2,'.')              CALL FMPRNT(MB)          ELSE              CALL FMNTRJ(MA,NDIG)              WRITE (KW,120) LREL              CALL FMNTRJ(MB,NDIG)          ENDIF      ENDIF!             JCOMP will be 1 if MA.GT.MB!                           2 if MA.EQ.MB!                           3 if MA.LT.MB!             Check for special cases.      IF (LREL.NE.'EQ' .AND. LREL.NE.'NE' .AND. LREL.NE.'LT' .AND.  &          LREL.NE.'GT' .AND. LREL.NE.'LE' .AND. LREL.NE.'GE') THEN          KFLAG = -4          FMCOMP = .FALSE.          IF (KWARN.LE.0) GO TO 170          WRITE (KW,130) LREL  130     FORMAT(/' ERROR OF TYPE KFLAG = -4 IN FM PACKAGE IN ROUTINE',  &                 ' FMCOMP'//1X,A,' IS NOT ONE OF THE SIX RECOGNIZED',  &                 ' COMPARISONS.'//' .FALSE. HAS BEEN RETURNED.'/)          GO TO 170      ENDIF      IF (MA(1).EQ.KUNKNO .OR. MB(1).EQ.KUNKNO) THEN          KFLAG = -4          FMCOMP = .FALSE.          GO TO 170      ENDIF      IF (ABS(MA(1)).EQ.KEXPOV .AND. MA(1).EQ.MB(1) .AND.  &          MA(2).EQ.MB(2)) THEN          KFLAG = -4          FMCOMP = .FALSE.          IF (KWARN.LE.0) GO TO 170          WRITE (KW,140)  140     FORMAT(/' ERROR OF TYPE KFLAG = -4 IN FM PACKAGE IN ROUTINE',  &                 ' FMCOMP'//' TWO NUMBERS IN THE SAME OVERFLOW OR',  &                 ' UNDERLOW CATEGORY CANNOT BE COMPARED.'//  &                 ' .FALSE. HAS BEEN RETURNED.'/)         GO TO 170      ENDIF!             Check for zero.      KFLAG = 0      IF (MA(2).EQ.0) THEN          JCOMP = 2          IF (MB(2).LT.0) JCOMP = 1          IF (MB(2).GT.0) JCOMP = 3          GO TO 160      ENDIF      IF (MB(2).EQ.0) THEN          JCOMP = 1          IF (MA(2).LT.0) JCOMP = 3          GO TO 160      ENDIF!             Check for opposite signs.      IF (MA(2).GT.0 .AND. MB(2).LT.0) THEN          JCOMP = 1          GO TO 160      ENDIF      IF (MB(2).GT.0 .AND. MA(2).LT.0) THEN          JCOMP = 3          GO TO 160      ENDIF!             See which one is larger in absolute value.      IF (MA(1).GT.MB(1)) THEN          JCOMP = 1          GO TO 160      ENDIF      IF (MB(1).GT.MA(1)) THEN          JCOMP = 3          GO TO 160      ENDIF      NLAST = NDIG + 1      DO 150 J = 2, NLAST         IF (ABS(MA(J)).GT.ABS(MB(J))) THEN             JCOMP = 1             GO TO 160         ENDIF         IF (ABS(MB(J)).GT.ABS(MA(J))) THEN             JCOMP = 3             GO TO 160         ENDIF  150 CONTINUE      JCOMP = 2!             Now match the JCOMP value to the requested comparison.  160 IF (JCOMP.EQ.1 .AND. MA(2).LT.0) THEN          JCOMP = 3      ELSE IF (JCOMP.EQ.3 .AND. MB(2).LT.0) THEN          JCOMP = 1      ENDIF      FMCOMP = .FALSE.      IF (JCOMP.EQ.1 .AND. (LREL.EQ.'GT' .OR. LREL.EQ.'GE' .OR.  &                            LREL.EQ.'NE')) FMCOMP = .TRUE.      IF (JCOMP.EQ.2 .AND. (LREL.EQ.'EQ' .OR. LREL.EQ.'GE' .OR.  &                            LREL.EQ.'LE')) FMCOMP = .TRUE.      IF (JCOMP.EQ.3 .AND. (LREL.EQ.'NE' .OR. LREL.EQ.'LT' .OR.  &                            LREL.EQ.'LE')) FMCOMP = .TRUE.  170 IF (NTRACE.NE.0) THEN          IF (NCALL.LE.LVLTRC .AND. ABS(NTRACE).GE.1) THEN              IF (KFLAG.EQ.0) THEN                  WRITE (KW,180) NCALL,JBASE,NDIG  180             FORMAT(' FMCOMP',15X,'CALL LEVEL =',I2,5X,'JBASE =',  &                         I10,5X,'NDIG =',I6)              ELSE                  WRITE (KW,190) NCALL,JBASE,NDIG,KFLAG  190             FORMAT(' FMCOMP',6X,'CALL LEVEL =',I2,4X,'JBASE =',  &                         I10,4X,'NDIG =',I6,4X,'KFLAG =',I3)              ENDIF              IF (FMCOMP) THEN                  WRITE (KW,200)  200            

⌨️ 快捷键说明

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