mpcmd.f 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. *DECK MPCMD
  2. SUBROUTINE MPCMD (X, DZ)
  3. C***BEGIN PROLOGUE MPCMD
  4. C***SUBSIDIARY
  5. C***PURPOSE Subsidiary to DQDOTA and DQDOTI
  6. C***LIBRARY SLATEC
  7. C***TYPE ALL (MPCMD-A)
  8. C***AUTHOR (UNKNOWN)
  9. C***DESCRIPTION
  10. C
  11. C Converts multiple-precision X to double-precision DZ. Assumes
  12. C X is in allowable range for double-precision numbers. There is
  13. C some loss of accuracy if the exponent is large.
  14. C
  15. C The argument X(*) is INTEGER array of size 30. See the comments in
  16. C the routine MPBLAS for the reason for this choice.
  17. C
  18. C***SEE ALSO DQDOTA, DQDOTI, MPBLAS
  19. C***ROUTINES CALLED MPCHK, MPERR
  20. C***COMMON BLOCKS MPCOM
  21. C***REVISION HISTORY (YYMMDD)
  22. C 791001 DATE WRITTEN
  23. C ?????? Modified for use with BLAS. Blank COMMON changed to named
  24. C COMMON. R given dimension 12.
  25. C 890531 Changed all specific intrinsics to generic. (WRB)
  26. C 891214 Prologue converted to Version 4.0 format. (BAB)
  27. C 900402 Added TYPE section. (WRB)
  28. C 930124 Increased Array size in MPCON for SUN -r8. (RWC)
  29. C***END PROLOGUE MPCMD
  30. DOUBLE PRECISION DB, DZ, DZ2
  31. COMMON /MPCOM/ B, T, M, LUN, MXR, R(30)
  32. INTEGER B, T, R, X(*), TM
  33. C***FIRST EXECUTABLE STATEMENT MPCMD
  34. CALL MPCHK (1, 4)
  35. DZ = 0D0
  36. IF (X(1).EQ.0) RETURN
  37. DB = DBLE(B)
  38. DO 10 I = 1, T
  39. DZ = DB*DZ + DBLE(X(I+2))
  40. TM = I
  41. C CHECK IF FULL DOUBLE-PRECISION ACCURACY ATTAINED
  42. DZ2 = DZ + 1D0
  43. C TEST BELOW NOT ALWAYS EQUIVALENT TO - IF (DZ2.LE.DZ) GO TO 20,
  44. C FOR EXAMPLE ON CYBER 76.
  45. IF ((DZ2-DZ).LE.0D0) GO TO 20
  46. 10 CONTINUE
  47. C NOW ALLOW FOR EXPONENT
  48. 20 DZ = DZ*(DB**(X(2)-TM))
  49. C CHECK REASONABLENESS OF RESULT.
  50. IF (DZ.LE.0D0) GO TO 30
  51. C LHS SHOULD BE .LE. 0.5 BUT ALLOW FOR SOME ERROR IN LOG
  52. IF (ABS(DBLE(X(2))-(LOG(DZ)/
  53. 1 LOG(DBLE(B))+0.5D0)).GT.0.6D0) GO TO 30
  54. IF (X(1).LT.0) DZ = -DZ
  55. RETURN
  56. C FOLLOWING MESSAGE INDICATES THAT X IS TOO LARGE OR SMALL -
  57. C TRY USING MPCMDE INSTEAD.
  58. 30 WRITE (LUN, 40)
  59. 40 FORMAT (' *** FLOATING-POINT OVER/UNDER-FLOW IN MPCMD ***')
  60. CALL MPERR
  61. RETURN
  62. END