mpnzr.f 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. *DECK MPNZR
  2. SUBROUTINE MPNZR (RS, RE, Z, TRUNC)
  3. C***BEGIN PROLOGUE MPNZR
  4. C***SUBSIDIARY
  5. C***PURPOSE Subsidiary to DQDOTA and DQDOTI
  6. C***LIBRARY SLATEC
  7. C***TYPE ALL (MPNZR-A)
  8. C***AUTHOR (UNKNOWN)
  9. C***DESCRIPTION
  10. C
  11. C Modified for use with BLAS. Blank COMMON changed to named COMMON.
  12. C Assumes long (i.e. (t+4)-DIGIT) fraction in R, sign = RS, exponent
  13. C = RE. Normalizes, and returns 'mp' result in Z. Integer arguments
  14. C RS and RE are not preserved. R*-rounding is used if TRUNC.EQ.0
  15. C
  16. C The argument Z(*) and the variable R in COMMON are INTEGER arrays
  17. C of size 30. See the comments in the routine MPBLAS for the reason
  18. C for this choice.
  19. C
  20. C***SEE ALSO DQDOTA, DQDOTI, MPBLAS
  21. C***ROUTINES CALLED MPERR, MPOVFL, MPUNFL
  22. C***COMMON BLOCKS MPCOM
  23. C***REVISION HISTORY (YYMMDD)
  24. C 791001 DATE WRITTEN
  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 MPNZR
  30. COMMON /MPCOM/ B, T, M, LUN, MXR, R(30)
  31. INTEGER B, T, R, Z(*), RE, RS, TRUNC, B2
  32. C***FIRST EXECUTABLE STATEMENT MPNZR
  33. I2 = T + 4
  34. IF (RS.NE.0) GO TO 20
  35. C STORE ZERO IN Z
  36. 10 Z(1) = 0
  37. RETURN
  38. C CHECK THAT SIGN = +-1
  39. 20 IF (ABS(RS).LE.1) GO TO 40
  40. WRITE (LUN, 30)
  41. 30 FORMAT (' *** SIGN NOT 0, +1 OR -1 IN CALL TO MPNZR,',
  42. 1 ' POSSIBLE OVERWRITING PROBLEM ***')
  43. CALL MPERR
  44. GO TO 10
  45. C LOOK FOR FIRST NONZERO DIGIT
  46. 40 DO 50 I = 1, I2
  47. IS = I - 1
  48. IF (R(I).GT.0) GO TO 60
  49. 50 CONTINUE
  50. C FRACTION ZERO
  51. GO TO 10
  52. 60 IF (IS.EQ.0) GO TO 90
  53. C NORMALIZE
  54. RE = RE - IS
  55. I2M = I2 - IS
  56. DO 70 J = 1, I2M
  57. K = J + IS
  58. 70 R(J) = R(K)
  59. I2P = I2M + 1
  60. DO 80 J = I2P, I2
  61. 80 R(J) = 0
  62. C CHECK TO SEE IF TRUNCATION IS DESIRED
  63. 90 IF (TRUNC.NE.0) GO TO 150
  64. C SEE IF ROUNDING NECESSARY
  65. C TREAT EVEN AND ODD BASES DIFFERENTLY
  66. B2 = B/2
  67. IF ((2*B2).NE.B) GO TO 130
  68. C B EVEN. ROUND IF R(T+1).GE.B2 UNLESS R(T) ODD AND ALL ZEROS
  69. C AFTER R(T+2).
  70. IF (R(T+1) - B2) 150, 100, 110
  71. 100 IF (MOD(R(T),2).EQ.0) GO TO 110
  72. IF ((R(T+2)+R(T+3)+R(T+4)).EQ.0) GO TO 150
  73. C ROUND
  74. 110 DO 120 J = 1, T
  75. I = T + 1 - J
  76. R(I) = R(I) + 1
  77. IF (R(I).LT.B) GO TO 150
  78. 120 R(I) = 0
  79. C EXCEPTIONAL CASE, ROUNDED UP TO .10000...
  80. RE = RE + 1
  81. R(1) = 1
  82. GO TO 150
  83. C ODD BASE, ROUND IF R(T+1)... .GT. 1/2
  84. 130 DO 140 I = 1, 4
  85. IT = T + I
  86. IF (R(IT) - B2) 150, 140, 110
  87. 140 CONTINUE
  88. C CHECK FOR OVERFLOW
  89. 150 IF (RE.LE.M) GO TO 170
  90. WRITE (LUN, 160)
  91. 160 FORMAT (' *** OVERFLOW OCCURRED IN MPNZR ***')
  92. CALL MPOVFL (Z)
  93. RETURN
  94. C CHECK FOR UNDERFLOW
  95. 170 IF (RE.LT.(-M)) GO TO 190
  96. C STORE RESULT IN Z
  97. Z(1) = RS
  98. Z(2) = RE
  99. DO 180 I = 1, T
  100. 180 Z(I+2) = R(I)
  101. RETURN
  102. C UNDERFLOW HERE
  103. 190 CALL MPUNFL (Z)
  104. RETURN
  105. END