You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

slamchf77.f 26 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924
  1. *> \brief \b SLAMCHF77 deprecated
  2. *
  3. * =========== DOCUMENTATION ===========
  4. *
  5. * Online html documentation available at
  6. * http://www.netlib.org/lapack/explore-html/
  7. *
  8. * Definition:
  9. * ===========
  10. *
  11. * REAL FUNCTION SLAMCH( CMACH )
  12. *
  13. * .. Scalar Arguments ..
  14. * CHARACTER CMACH
  15. * ..
  16. *
  17. *
  18. *> \par Purpose:
  19. * =============
  20. *>
  21. *> \verbatim
  22. *>
  23. *> SLAMCH determines single precision machine parameters.
  24. *> \endverbatim
  25. *
  26. * Arguments:
  27. * ==========
  28. *
  29. *> \param[in] CMACH
  30. *> \verbatim
  31. *> Specifies the value to be returned by SLAMCH:
  32. *> = 'E' or 'e', SLAMCH := eps
  33. *> = 'S' or 's , SLAMCH := sfmin
  34. *> = 'B' or 'b', SLAMCH := base
  35. *> = 'P' or 'p', SLAMCH := eps*base
  36. *> = 'N' or 'n', SLAMCH := t
  37. *> = 'R' or 'r', SLAMCH := rnd
  38. *> = 'M' or 'm', SLAMCH := emin
  39. *> = 'U' or 'u', SLAMCH := rmin
  40. *> = 'L' or 'l', SLAMCH := emax
  41. *> = 'O' or 'o', SLAMCH := rmax
  42. *> where
  43. *> eps = relative machine precision
  44. *> sfmin = safe minimum, such that 1/sfmin does not overflow
  45. *> base = base of the machine
  46. *> prec = eps*base
  47. *> t = number of (base) digits in the mantissa
  48. *> rnd = 1.0 when rounding occurs in addition, 0.0 otherwise
  49. *> emin = minimum exponent before (gradual) underflow
  50. *> rmin = underflow threshold - base**(emin-1)
  51. *> emax = largest exponent before overflow
  52. *> rmax = overflow threshold - (base**emax)*(1-eps)
  53. *> \endverbatim
  54. *
  55. * Authors:
  56. * ========
  57. *
  58. *> \author Univ. of Tennessee
  59. *> \author Univ. of California Berkeley
  60. *> \author Univ. of Colorado Denver
  61. *> \author NAG Ltd.
  62. *
  63. *> \date April 2012
  64. *
  65. *> \ingroup auxOTHERauxiliary
  66. *
  67. * =====================================================================
  68. REAL FUNCTION SLAMCH( CMACH )
  69. *
  70. * -- LAPACK auxiliary routine (version 3.7.0) --
  71. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  72. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  73. * April 2012
  74. *
  75. * .. Scalar Arguments ..
  76. CHARACTER CMACH
  77. * ..
  78. * .. Parameters ..
  79. REAL ONE, ZERO
  80. PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 )
  81. * ..
  82. * .. Local Scalars ..
  83. LOGICAL FIRST, LRND
  84. INTEGER BETA, IMAX, IMIN, IT
  85. REAL BASE, EMAX, EMIN, EPS, PREC, RMACH, RMAX, RMIN,
  86. $ RND, SFMIN, SMALL, T
  87. * ..
  88. * .. External Functions ..
  89. LOGICAL LSAME
  90. EXTERNAL LSAME
  91. * ..
  92. * .. External Subroutines ..
  93. EXTERNAL SLAMC2
  94. * ..
  95. * .. Save statement ..
  96. SAVE FIRST, EPS, SFMIN, BASE, T, RND, EMIN, RMIN,
  97. $ EMAX, RMAX, PREC
  98. * ..
  99. * .. Data statements ..
  100. DATA FIRST / .TRUE. /
  101. * ..
  102. * .. Executable Statements ..
  103. *
  104. IF( FIRST ) THEN
  105. CALL SLAMC2( BETA, IT, LRND, EPS, IMIN, RMIN, IMAX, RMAX )
  106. BASE = BETA
  107. T = IT
  108. IF( LRND ) THEN
  109. RND = ONE
  110. EPS = ( BASE**( 1-IT ) ) / 2
  111. ELSE
  112. RND = ZERO
  113. EPS = BASE**( 1-IT )
  114. END IF
  115. PREC = EPS*BASE
  116. EMIN = IMIN
  117. EMAX = IMAX
  118. SFMIN = RMIN
  119. SMALL = ONE / RMAX
  120. IF( SMALL.GE.SFMIN ) THEN
  121. *
  122. * Use SMALL plus a bit, to avoid the possibility of rounding
  123. * causing overflow when computing 1/sfmin.
  124. *
  125. SFMIN = SMALL*( ONE+EPS )
  126. END IF
  127. END IF
  128. *
  129. IF( LSAME( CMACH, 'E' ) ) THEN
  130. RMACH = EPS
  131. ELSE IF( LSAME( CMACH, 'S' ) ) THEN
  132. RMACH = SFMIN
  133. ELSE IF( LSAME( CMACH, 'B' ) ) THEN
  134. RMACH = BASE
  135. ELSE IF( LSAME( CMACH, 'P' ) ) THEN
  136. RMACH = PREC
  137. ELSE IF( LSAME( CMACH, 'N' ) ) THEN
  138. RMACH = T
  139. ELSE IF( LSAME( CMACH, 'R' ) ) THEN
  140. RMACH = RND
  141. ELSE IF( LSAME( CMACH, 'M' ) ) THEN
  142. RMACH = EMIN
  143. ELSE IF( LSAME( CMACH, 'U' ) ) THEN
  144. RMACH = RMIN
  145. ELSE IF( LSAME( CMACH, 'L' ) ) THEN
  146. RMACH = EMAX
  147. ELSE IF( LSAME( CMACH, 'O' ) ) THEN
  148. RMACH = RMAX
  149. END IF
  150. *
  151. SLAMCH = RMACH
  152. FIRST = .FALSE.
  153. RETURN
  154. *
  155. * End of SLAMCH
  156. *
  157. END
  158. *
  159. ************************************************************************
  160. *
  161. *> \brief \b SLAMC1
  162. *> \details
  163. *> \b Purpose:
  164. *> \verbatim
  165. *> SLAMC1 determines the machine parameters given by BETA, T, RND, and
  166. *> IEEE1.
  167. *> \endverbatim
  168. *>
  169. *> \param[out] BETA
  170. *> \verbatim
  171. *> The base of the machine.
  172. *> \endverbatim
  173. *>
  174. *> \param[out] T
  175. *> \verbatim
  176. *> The number of ( BETA ) digits in the mantissa.
  177. *> \endverbatim
  178. *>
  179. *> \param[out] RND
  180. *> \verbatim
  181. *> Specifies whether proper rounding ( RND = .TRUE. ) or
  182. *> chopping ( RND = .FALSE. ) occurs in addition. This may not
  183. *> be a reliable guide to the way in which the machine performs
  184. *> its arithmetic.
  185. *> \endverbatim
  186. *>
  187. *> \param[out] IEEE1
  188. *> \verbatim
  189. *> Specifies whether rounding appears to be done in the IEEE
  190. *> 'round to nearest' style.
  191. *> \endverbatim
  192. *> \author LAPACK is a software package provided by Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..
  193. *> \date April 2012
  194. *> \ingroup auxOTHERauxiliary
  195. *>
  196. *> \details \b Further \b Details
  197. *> \verbatim
  198. *>
  199. *> The routine is based on the routine ENVRON by Malcolm and
  200. *> incorporates suggestions by Gentleman and Marovich. See
  201. *>
  202. *> Malcolm M. A. (1972) Algorithms to reveal properties of
  203. *> floating-point arithmetic. Comms. of the ACM, 15, 949-951.
  204. *>
  205. *> Gentleman W. M. and Marovich S. B. (1974) More on algorithms
  206. *> that reveal properties of floating point arithmetic units.
  207. *> Comms. of the ACM, 17, 276-277.
  208. *> \endverbatim
  209. *>
  210. SUBROUTINE SLAMC1( BETA, T, RND, IEEE1 )
  211. *
  212. * -- LAPACK auxiliary routine (version 3.7.0) --
  213. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  214. * November 2010
  215. *
  216. * .. Scalar Arguments ..
  217. LOGICAL IEEE1, RND
  218. INTEGER BETA, T
  219. * ..
  220. * =====================================================================
  221. *
  222. * .. Local Scalars ..
  223. LOGICAL FIRST, LIEEE1, LRND
  224. INTEGER LBETA, LT
  225. REAL A, B, C, F, ONE, QTR, SAVEC, T1, T2
  226. * ..
  227. * .. External Functions ..
  228. REAL SLAMC3
  229. EXTERNAL SLAMC3
  230. * ..
  231. * .. Save statement ..
  232. SAVE FIRST, LIEEE1, LBETA, LRND, LT
  233. * ..
  234. * .. Data statements ..
  235. DATA FIRST / .TRUE. /
  236. * ..
  237. * .. Executable Statements ..
  238. *
  239. IF( FIRST ) THEN
  240. ONE = 1
  241. *
  242. * LBETA, LIEEE1, LT and LRND are the local values of BETA,
  243. * IEEE1, T and RND.
  244. *
  245. * Throughout this routine we use the function SLAMC3 to ensure
  246. * that relevant values are stored and not held in registers, or
  247. * are not affected by optimizers.
  248. *
  249. * Compute a = 2.0**m with the smallest positive integer m such
  250. * that
  251. *
  252. * fl( a + 1.0 ) = a.
  253. *
  254. A = 1
  255. C = 1
  256. *
  257. *+ WHILE( C.EQ.ONE )LOOP
  258. 10 CONTINUE
  259. IF( C.EQ.ONE ) THEN
  260. A = 2*A
  261. C = SLAMC3( A, ONE )
  262. C = SLAMC3( C, -A )
  263. GO TO 10
  264. END IF
  265. *+ END WHILE
  266. *
  267. * Now compute b = 2.0**m with the smallest positive integer m
  268. * such that
  269. *
  270. * fl( a + b ) .gt. a.
  271. *
  272. B = 1
  273. C = SLAMC3( A, B )
  274. *
  275. *+ WHILE( C.EQ.A )LOOP
  276. 20 CONTINUE
  277. IF( C.EQ.A ) THEN
  278. B = 2*B
  279. C = SLAMC3( A, B )
  280. GO TO 20
  281. END IF
  282. *+ END WHILE
  283. *
  284. * Now compute the base. a and c are neighbouring floating point
  285. * numbers in the interval ( beta**t, beta**( t + 1 ) ) and so
  286. * their difference is beta. Adding 0.25 to c is to ensure that it
  287. * is truncated to beta and not ( beta - 1 ).
  288. *
  289. QTR = ONE / 4
  290. SAVEC = C
  291. C = SLAMC3( C, -A )
  292. LBETA = C + QTR
  293. *
  294. * Now determine whether rounding or chopping occurs, by adding a
  295. * bit less than beta/2 and a bit more than beta/2 to a.
  296. *
  297. B = LBETA
  298. F = SLAMC3( B / 2, -B / 100 )
  299. C = SLAMC3( F, A )
  300. IF( C.EQ.A ) THEN
  301. LRND = .TRUE.
  302. ELSE
  303. LRND = .FALSE.
  304. END IF
  305. F = SLAMC3( B / 2, B / 100 )
  306. C = SLAMC3( F, A )
  307. IF( ( LRND ) .AND. ( C.EQ.A ) )
  308. $ LRND = .FALSE.
  309. *
  310. * Try and decide whether rounding is done in the IEEE 'round to
  311. * nearest' style. B/2 is half a unit in the last place of the two
  312. * numbers A and SAVEC. Furthermore, A is even, i.e. has last bit
  313. * zero, and SAVEC is odd. Thus adding B/2 to A should not change
  314. * A, but adding B/2 to SAVEC should change SAVEC.
  315. *
  316. T1 = SLAMC3( B / 2, A )
  317. T2 = SLAMC3( B / 2, SAVEC )
  318. LIEEE1 = ( T1.EQ.A ) .AND. ( T2.GT.SAVEC ) .AND. LRND
  319. *
  320. * Now find the mantissa, t. It should be the integer part of
  321. * log to the base beta of a, however it is safer to determine t
  322. * by powering. So we find t as the smallest positive integer for
  323. * which
  324. *
  325. * fl( beta**t + 1.0 ) = 1.0.
  326. *
  327. LT = 0
  328. A = 1
  329. C = 1
  330. *
  331. *+ WHILE( C.EQ.ONE )LOOP
  332. 30 CONTINUE
  333. IF( C.EQ.ONE ) THEN
  334. LT = LT + 1
  335. A = A*LBETA
  336. C = SLAMC3( A, ONE )
  337. C = SLAMC3( C, -A )
  338. GO TO 30
  339. END IF
  340. *+ END WHILE
  341. *
  342. END IF
  343. *
  344. BETA = LBETA
  345. T = LT
  346. RND = LRND
  347. IEEE1 = LIEEE1
  348. FIRST = .FALSE.
  349. RETURN
  350. *
  351. * End of SLAMC1
  352. *
  353. END
  354. *
  355. ************************************************************************
  356. *
  357. *> \brief \b SLAMC2
  358. *> \details
  359. *> \b Purpose:
  360. *> \verbatim
  361. *> SLAMC2 determines the machine parameters specified in its argument
  362. *> list.
  363. *> \endverbatim
  364. *> \author LAPACK is a software package provided by Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..
  365. *> \date April 2012
  366. *> \ingroup auxOTHERauxiliary
  367. *>
  368. *> \param[out] BETA
  369. *> \verbatim
  370. *> The base of the machine.
  371. *> \endverbatim
  372. *>
  373. *> \param[out] T
  374. *> \verbatim
  375. *> The number of ( BETA ) digits in the mantissa.
  376. *> \endverbatim
  377. *>
  378. *> \param[out] RND
  379. *> \verbatim
  380. *> Specifies whether proper rounding ( RND = .TRUE. ) or
  381. *> chopping ( RND = .FALSE. ) occurs in addition. This may not
  382. *> be a reliable guide to the way in which the machine performs
  383. *> its arithmetic.
  384. *> \endverbatim
  385. *>
  386. *> \param[out] EPS
  387. *> \verbatim
  388. *> The smallest positive number such that
  389. *> fl( 1.0 - EPS ) .LT. 1.0,
  390. *> where fl denotes the computed value.
  391. *> \endverbatim
  392. *>
  393. *> \param[out] EMIN
  394. *> \verbatim
  395. *> The minimum exponent before (gradual) underflow occurs.
  396. *> \endverbatim
  397. *>
  398. *> \param[out] RMIN
  399. *> \verbatim
  400. *> The smallest normalized number for the machine, given by
  401. *> BASE**( EMIN - 1 ), where BASE is the floating point value
  402. *> of BETA.
  403. *> \endverbatim
  404. *>
  405. *> \param[out] EMAX
  406. *> \verbatim
  407. *> The maximum exponent before overflow occurs.
  408. *> \endverbatim
  409. *>
  410. *> \param[out] RMAX
  411. *> \verbatim
  412. *> The largest positive number for the machine, given by
  413. *> BASE**EMAX * ( 1 - EPS ), where BASE is the floating point
  414. *> value of BETA.
  415. *> \endverbatim
  416. *>
  417. *> \details \b Further \b Details
  418. *> \verbatim
  419. *>
  420. *> The computation of EPS is based on a routine PARANOIA by
  421. *> W. Kahan of the University of California at Berkeley.
  422. *> \endverbatim
  423. SUBROUTINE SLAMC2( BETA, T, RND, EPS, EMIN, RMIN, EMAX, RMAX )
  424. *
  425. * -- LAPACK auxiliary routine (version 3.7.0) --
  426. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  427. * November 2010
  428. *
  429. * .. Scalar Arguments ..
  430. LOGICAL RND
  431. INTEGER BETA, EMAX, EMIN, T
  432. REAL EPS, RMAX, RMIN
  433. * ..
  434. * =====================================================================
  435. *
  436. * .. Local Scalars ..
  437. LOGICAL FIRST, IEEE, IWARN, LIEEE1, LRND
  438. INTEGER GNMIN, GPMIN, I, LBETA, LEMAX, LEMIN, LT,
  439. $ NGNMIN, NGPMIN
  440. REAL A, B, C, HALF, LEPS, LRMAX, LRMIN, ONE, RBASE,
  441. $ SIXTH, SMALL, THIRD, TWO, ZERO
  442. * ..
  443. * .. External Functions ..
  444. REAL SLAMC3
  445. EXTERNAL SLAMC3
  446. * ..
  447. * .. External Subroutines ..
  448. EXTERNAL SLAMC1, SLAMC4, SLAMC5
  449. * ..
  450. * .. Intrinsic Functions ..
  451. INTRINSIC ABS, MAX, MIN
  452. * ..
  453. * .. Save statement ..
  454. SAVE FIRST, IWARN, LBETA, LEMAX, LEMIN, LEPS, LRMAX,
  455. $ LRMIN, LT
  456. * ..
  457. * .. Data statements ..
  458. DATA FIRST / .TRUE. / , IWARN / .FALSE. /
  459. * ..
  460. * .. Executable Statements ..
  461. *
  462. IF( FIRST ) THEN
  463. ZERO = 0
  464. ONE = 1
  465. TWO = 2
  466. *
  467. * LBETA, LT, LRND, LEPS, LEMIN and LRMIN are the local values of
  468. * BETA, T, RND, EPS, EMIN and RMIN.
  469. *
  470. * Throughout this routine we use the function SLAMC3 to ensure
  471. * that relevant values are stored and not held in registers, or
  472. * are not affected by optimizers.
  473. *
  474. * SLAMC1 returns the parameters LBETA, LT, LRND and LIEEE1.
  475. *
  476. CALL SLAMC1( LBETA, LT, LRND, LIEEE1 )
  477. *
  478. * Start to find EPS.
  479. *
  480. B = LBETA
  481. A = B**( -LT )
  482. LEPS = A
  483. *
  484. * Try some tricks to see whether or not this is the correct EPS.
  485. *
  486. B = TWO / 3
  487. HALF = ONE / 2
  488. SIXTH = SLAMC3( B, -HALF )
  489. THIRD = SLAMC3( SIXTH, SIXTH )
  490. B = SLAMC3( THIRD, -HALF )
  491. B = SLAMC3( B, SIXTH )
  492. B = ABS( B )
  493. IF( B.LT.LEPS )
  494. $ B = LEPS
  495. *
  496. LEPS = 1
  497. *
  498. *+ WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP
  499. 10 CONTINUE
  500. IF( ( LEPS.GT.B ) .AND. ( B.GT.ZERO ) ) THEN
  501. LEPS = B
  502. C = SLAMC3( HALF*LEPS, ( TWO**5 )*( LEPS**2 ) )
  503. C = SLAMC3( HALF, -C )
  504. B = SLAMC3( HALF, C )
  505. C = SLAMC3( HALF, -B )
  506. B = SLAMC3( HALF, C )
  507. GO TO 10
  508. END IF
  509. *+ END WHILE
  510. *
  511. IF( A.LT.LEPS )
  512. $ LEPS = A
  513. *
  514. * Computation of EPS complete.
  515. *
  516. * Now find EMIN. Let A = + or - 1, and + or - (1 + BASE**(-3)).
  517. * Keep dividing A by BETA until (gradual) underflow occurs. This
  518. * is detected when we cannot recover the previous A.
  519. *
  520. RBASE = ONE / LBETA
  521. SMALL = ONE
  522. DO 20 I = 1, 3
  523. SMALL = SLAMC3( SMALL*RBASE, ZERO )
  524. 20 CONTINUE
  525. A = SLAMC3( ONE, SMALL )
  526. CALL SLAMC4( NGPMIN, ONE, LBETA )
  527. CALL SLAMC4( NGNMIN, -ONE, LBETA )
  528. CALL SLAMC4( GPMIN, A, LBETA )
  529. CALL SLAMC4( GNMIN, -A, LBETA )
  530. IEEE = .FALSE.
  531. *
  532. IF( ( NGPMIN.EQ.NGNMIN ) .AND. ( GPMIN.EQ.GNMIN ) ) THEN
  533. IF( NGPMIN.EQ.GPMIN ) THEN
  534. LEMIN = NGPMIN
  535. * ( Non twos-complement machines, no gradual underflow;
  536. * e.g., VAX )
  537. ELSE IF( ( GPMIN-NGPMIN ).EQ.3 ) THEN
  538. LEMIN = NGPMIN - 1 + LT
  539. IEEE = .TRUE.
  540. * ( Non twos-complement machines, with gradual underflow;
  541. * e.g., IEEE standard followers )
  542. ELSE
  543. LEMIN = MIN( NGPMIN, GPMIN )
  544. * ( A guess; no known machine )
  545. IWARN = .TRUE.
  546. END IF
  547. *
  548. ELSE IF( ( NGPMIN.EQ.GPMIN ) .AND. ( NGNMIN.EQ.GNMIN ) ) THEN
  549. IF( ABS( NGPMIN-NGNMIN ).EQ.1 ) THEN
  550. LEMIN = MAX( NGPMIN, NGNMIN )
  551. * ( Twos-complement machines, no gradual underflow;
  552. * e.g., CYBER 205 )
  553. ELSE
  554. LEMIN = MIN( NGPMIN, NGNMIN )
  555. * ( A guess; no known machine )
  556. IWARN = .TRUE.
  557. END IF
  558. *
  559. ELSE IF( ( ABS( NGPMIN-NGNMIN ).EQ.1 ) .AND.
  560. $ ( GPMIN.EQ.GNMIN ) ) THEN
  561. IF( ( GPMIN-MIN( NGPMIN, NGNMIN ) ).EQ.3 ) THEN
  562. LEMIN = MAX( NGPMIN, NGNMIN ) - 1 + LT
  563. * ( Twos-complement machines with gradual underflow;
  564. * no known machine )
  565. ELSE
  566. LEMIN = MIN( NGPMIN, NGNMIN )
  567. * ( A guess; no known machine )
  568. IWARN = .TRUE.
  569. END IF
  570. *
  571. ELSE
  572. LEMIN = MIN( NGPMIN, NGNMIN, GPMIN, GNMIN )
  573. * ( A guess; no known machine )
  574. IWARN = .TRUE.
  575. END IF
  576. FIRST = .FALSE.
  577. ***
  578. * Comment out this if block if EMIN is ok
  579. IF( IWARN ) THEN
  580. FIRST = .TRUE.
  581. WRITE( 6, FMT = 9999 )LEMIN
  582. END IF
  583. ***
  584. *
  585. * Assume IEEE arithmetic if we found denormalised numbers above,
  586. * or if arithmetic seems to round in the IEEE style, determined
  587. * in routine SLAMC1. A true IEEE machine should have both things
  588. * true; however, faulty machines may have one or the other.
  589. *
  590. IEEE = IEEE .OR. LIEEE1
  591. *
  592. * Compute RMIN by successive division by BETA. We could compute
  593. * RMIN as BASE**( EMIN - 1 ), but some machines underflow during
  594. * this computation.
  595. *
  596. LRMIN = 1
  597. DO 30 I = 1, 1 - LEMIN
  598. LRMIN = SLAMC3( LRMIN*RBASE, ZERO )
  599. 30 CONTINUE
  600. *
  601. * Finally, call SLAMC5 to compute EMAX and RMAX.
  602. *
  603. CALL SLAMC5( LBETA, LT, LEMIN, IEEE, LEMAX, LRMAX )
  604. END IF
  605. *
  606. BETA = LBETA
  607. T = LT
  608. RND = LRND
  609. EPS = LEPS
  610. EMIN = LEMIN
  611. RMIN = LRMIN
  612. EMAX = LEMAX
  613. RMAX = LRMAX
  614. *
  615. RETURN
  616. *
  617. 9999 FORMAT( / / ' WARNING. The value EMIN may be incorrect:-',
  618. $ ' EMIN = ', I8, /
  619. $ ' If, after inspection, the value EMIN looks',
  620. $ ' acceptable please comment out ',
  621. $ / ' the IF block as marked within the code of routine',
  622. $ ' SLAMC2,', / ' otherwise supply EMIN explicitly.', / )
  623. *
  624. * End of SLAMC2
  625. *
  626. END
  627. *
  628. ************************************************************************
  629. *
  630. *> \brief \b SLAMC3
  631. *> \details
  632. *> \b Purpose:
  633. *> \verbatim
  634. *> SLAMC3 is intended to force A and B to be stored prior to doing
  635. *> the addition of A and B , for use in situations where optimizers
  636. *> might hold one of these in a register.
  637. *> \endverbatim
  638. *>
  639. *> \param[in] A
  640. *>
  641. *> \param[in] B
  642. *> \verbatim
  643. *> The values A and B.
  644. *> \endverbatim
  645. REAL FUNCTION SLAMC3( A, B )
  646. *
  647. * -- LAPACK auxiliary routine (version 3.7.0) --
  648. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  649. * November 2010
  650. *
  651. * .. Scalar Arguments ..
  652. REAL A, B
  653. * ..
  654. * =====================================================================
  655. *
  656. * .. Executable Statements ..
  657. *
  658. SLAMC3 = A + B
  659. *
  660. RETURN
  661. *
  662. * End of SLAMC3
  663. *
  664. END
  665. *
  666. ************************************************************************
  667. *
  668. *> \brief \b SLAMC4
  669. *> \details
  670. *> \b Purpose:
  671. *> \verbatim
  672. *> SLAMC4 is a service routine for SLAMC2.
  673. *> \endverbatim
  674. *>
  675. *> \param[out] EMIN
  676. *> \verbatim
  677. *> The minimum exponent before (gradual) underflow, computed by
  678. *> setting A = START and dividing by BASE until the previous A
  679. *> can not be recovered.
  680. *> \endverbatim
  681. *>
  682. *> \param[in] START
  683. *> \verbatim
  684. *> The starting point for determining EMIN.
  685. *> \endverbatim
  686. *>
  687. *> \param[in] BASE
  688. *> \verbatim
  689. *> The base of the machine.
  690. *> \endverbatim
  691. *>
  692. SUBROUTINE SLAMC4( EMIN, START, BASE )
  693. *
  694. * -- LAPACK auxiliary routine (version 3.7.0) --
  695. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  696. * November 2010
  697. *
  698. * .. Scalar Arguments ..
  699. INTEGER BASE
  700. INTEGER EMIN
  701. REAL START
  702. * ..
  703. * =====================================================================
  704. *
  705. * .. Local Scalars ..
  706. INTEGER I
  707. REAL A, B1, B2, C1, C2, D1, D2, ONE, RBASE, ZERO
  708. * ..
  709. * .. External Functions ..
  710. REAL SLAMC3
  711. EXTERNAL SLAMC3
  712. * ..
  713. * .. Executable Statements ..
  714. *
  715. A = START
  716. ONE = 1
  717. RBASE = ONE / BASE
  718. ZERO = 0
  719. EMIN = 1
  720. B1 = SLAMC3( A*RBASE, ZERO )
  721. C1 = A
  722. C2 = A
  723. D1 = A
  724. D2 = A
  725. *+ WHILE( ( C1.EQ.A ).AND.( C2.EQ.A ).AND.
  726. * $ ( D1.EQ.A ).AND.( D2.EQ.A ) )LOOP
  727. 10 CONTINUE
  728. IF( ( C1.EQ.A ) .AND. ( C2.EQ.A ) .AND. ( D1.EQ.A ) .AND.
  729. $ ( D2.EQ.A ) ) THEN
  730. EMIN = EMIN - 1
  731. A = B1
  732. B1 = SLAMC3( A / BASE, ZERO )
  733. C1 = SLAMC3( B1*BASE, ZERO )
  734. D1 = ZERO
  735. DO 20 I = 1, BASE
  736. D1 = D1 + B1
  737. 20 CONTINUE
  738. B2 = SLAMC3( A*RBASE, ZERO )
  739. C2 = SLAMC3( B2 / RBASE, ZERO )
  740. D2 = ZERO
  741. DO 30 I = 1, BASE
  742. D2 = D2 + B2
  743. 30 CONTINUE
  744. GO TO 10
  745. END IF
  746. *+ END WHILE
  747. *
  748. RETURN
  749. *
  750. * End of SLAMC4
  751. *
  752. END
  753. *
  754. ************************************************************************
  755. *
  756. *> \brief \b SLAMC5
  757. *> \details
  758. *> \b Purpose:
  759. *> \verbatim
  760. *> SLAMC5 attempts to compute RMAX, the largest machine floating-point
  761. *> number, without overflow. It assumes that EMAX + abs(EMIN) sum
  762. *> approximately to a power of 2. It will fail on machines where this
  763. *> assumption does not hold, for example, the Cyber 205 (EMIN = -28625,
  764. *> EMAX = 28718). It will also fail if the value supplied for EMIN is
  765. *> too large (i.e. too close to zero), probably with overflow.
  766. *> \endverbatim
  767. *>
  768. *> \param[in] BETA
  769. *> \verbatim
  770. *> The base of floating-point arithmetic.
  771. *> \endverbatim
  772. *>
  773. *> \param[in] P
  774. *> \verbatim
  775. *> The number of base BETA digits in the mantissa of a
  776. *> floating-point value.
  777. *> \endverbatim
  778. *>
  779. *> \param[in] EMIN
  780. *> \verbatim
  781. *> The minimum exponent before (gradual) underflow.
  782. *> \endverbatim
  783. *>
  784. *> \param[in] IEEE
  785. *> \verbatim
  786. *> A logical flag specifying whether or not the arithmetic
  787. *> system is thought to comply with the IEEE standard.
  788. *> \endverbatim
  789. *>
  790. *> \param[out] EMAX
  791. *> \verbatim
  792. *> The largest exponent before overflow
  793. *> \endverbatim
  794. *>
  795. *> \param[out] RMAX
  796. *> \verbatim
  797. *> The largest machine floating-point number.
  798. *> \endverbatim
  799. *>
  800. SUBROUTINE SLAMC5( BETA, P, EMIN, IEEE, EMAX, RMAX )
  801. *
  802. * -- LAPACK auxiliary routine (version 3.7.0) --
  803. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  804. * November 2010
  805. *
  806. * .. Scalar Arguments ..
  807. LOGICAL IEEE
  808. INTEGER BETA, EMAX, EMIN, P
  809. REAL RMAX
  810. * ..
  811. * =====================================================================
  812. *
  813. * .. Parameters ..
  814. REAL ZERO, ONE
  815. PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 )
  816. * ..
  817. * .. Local Scalars ..
  818. INTEGER EXBITS, EXPSUM, I, LEXP, NBITS, TRY, UEXP
  819. REAL OLDY, RECBAS, Y, Z
  820. * ..
  821. * .. External Functions ..
  822. REAL SLAMC3
  823. EXTERNAL SLAMC3
  824. * ..
  825. * .. Intrinsic Functions ..
  826. INTRINSIC MOD
  827. * ..
  828. * .. Executable Statements ..
  829. *
  830. * First compute LEXP and UEXP, two powers of 2 that bound
  831. * abs(EMIN). We then assume that EMAX + abs(EMIN) will sum
  832. * approximately to the bound that is closest to abs(EMIN).
  833. * (EMAX is the exponent of the required number RMAX).
  834. *
  835. LEXP = 1
  836. EXBITS = 1
  837. 10 CONTINUE
  838. TRY = LEXP*2
  839. IF( TRY.LE.( -EMIN ) ) THEN
  840. LEXP = TRY
  841. EXBITS = EXBITS + 1
  842. GO TO 10
  843. END IF
  844. IF( LEXP.EQ.-EMIN ) THEN
  845. UEXP = LEXP
  846. ELSE
  847. UEXP = TRY
  848. EXBITS = EXBITS + 1
  849. END IF
  850. *
  851. * Now -LEXP is less than or equal to EMIN, and -UEXP is greater
  852. * than or equal to EMIN. EXBITS is the number of bits needed to
  853. * store the exponent.
  854. *
  855. IF( ( UEXP+EMIN ).GT.( -LEXP-EMIN ) ) THEN
  856. EXPSUM = 2*LEXP
  857. ELSE
  858. EXPSUM = 2*UEXP
  859. END IF
  860. *
  861. * EXPSUM is the exponent range, approximately equal to
  862. * EMAX - EMIN + 1 .
  863. *
  864. EMAX = EXPSUM + EMIN - 1
  865. NBITS = 1 + EXBITS + P
  866. *
  867. * NBITS is the total number of bits needed to store a
  868. * floating-point number.
  869. *
  870. IF( ( MOD( NBITS, 2 ).EQ.1 ) .AND. ( BETA.EQ.2 ) ) THEN
  871. *
  872. * Either there are an odd number of bits used to store a
  873. * floating-point number, which is unlikely, or some bits are
  874. * not used in the representation of numbers, which is possible,
  875. * (e.g. Cray machines) or the mantissa has an implicit bit,
  876. * (e.g. IEEE machines, Dec Vax machines), which is perhaps the
  877. * most likely. We have to assume the last alternative.
  878. * If this is true, then we need to reduce EMAX by one because
  879. * there must be some way of representing zero in an implicit-bit
  880. * system. On machines like Cray, we are reducing EMAX by one
  881. * unnecessarily.
  882. *
  883. EMAX = EMAX - 1
  884. END IF
  885. *
  886. IF( IEEE ) THEN
  887. *
  888. * Assume we are on an IEEE machine which reserves one exponent
  889. * for infinity and NaN.
  890. *
  891. EMAX = EMAX - 1
  892. END IF
  893. *
  894. * Now create RMAX, the largest machine number, which should
  895. * be equal to (1.0 - BETA**(-P)) * BETA**EMAX .
  896. *
  897. * First compute 1.0 - BETA**(-P), being careful that the
  898. * result is less than 1.0 .
  899. *
  900. RECBAS = ONE / BETA
  901. Z = BETA - ONE
  902. Y = ZERO
  903. DO 20 I = 1, P
  904. Z = Z*RECBAS
  905. IF( Y.LT.ONE )
  906. $ OLDY = Y
  907. Y = SLAMC3( Y, Z )
  908. 20 CONTINUE
  909. IF( Y.GE.ONE )
  910. $ Y = OLDY
  911. *
  912. * Now multiply by BETA**EMAX to get RMAX.
  913. *
  914. DO 30 I = 1, EMAX
  915. Y = SLAMC3( Y*BETA, ZERO )
  916. 30 CONTINUE
  917. *
  918. RMAX = Y
  919. RETURN
  920. *
  921. * End of SLAMC5
  922. *
  923. END