ieetst.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. /* Floating point to ASCII input and output string test program.
  2. *
  3. * Numbers in the native machine data structure are converted
  4. * to e type, then to and from decimal ASCII strings. Native
  5. * printf() and scanf() functions are also used to produce
  6. * and read strings. The resulting e type binary values
  7. * are compared, with diagnostic printouts of any discrepancies.
  8. *
  9. * Steve Moshier, 16 Dec 88
  10. * last revision: 16 May 92
  11. */
  12. #include "ehead.h"
  13. #include "mconf.h"
  14. /* Include tests of 80-bit long double precision: */
  15. #define LDOUBLE 0
  16. /* Abort subtest after getting this many errors: */
  17. #define MAXERR 5
  18. /* Number of random arguments to try (set as large as you have
  19. * patience for): */
  20. #define NRAND 100
  21. /* Perform internal consistency test: */
  22. #define CHKINTERNAL 0
  23. static unsigned short fullp[NE], rounded[NE];
  24. float prec24, sprec24, ssprec24;
  25. double prec53, sprec53, ssprec53;
  26. #if LDOUBLE
  27. long double prec64, sprec64, ssprec64;
  28. #endif
  29. static unsigned short rprint[NE], rscan[NE];
  30. static unsigned short q1[NE], q2[NE], q5[NE];
  31. static unsigned short e1[NE], e2[NE], e3[NE];
  32. static double d1, d2;
  33. static int errprint = 0;
  34. static int errscan = 0;
  35. static int identerr = 0;
  36. static int errtot = 0;
  37. static int count = 0;
  38. static char str0[80], str1[80], str2[80], str3[80];
  39. static unsigned short eten[NE], maxm[NE];
  40. int m, n, k2, mprec, SPREC;
  41. char *Ten = "10.0";
  42. char tformat[10];
  43. char *format24 = "%.8e";
  44. #ifdef DEC
  45. char *format53 = "%.17e";
  46. #else
  47. char *format53 = "%.16e";
  48. #endif
  49. char *fformat24 = "%e";
  50. char *fformat53 = "%le";
  51. char *pct = "%";
  52. char *quo = "\042";
  53. #if LDOUBLE
  54. char *format64 = "%.20Le";
  55. char *fformat64 = "%Le";
  56. #endif
  57. char *format;
  58. char *fformat;
  59. char *toomany = "Too many errors; aborting this test.\n";
  60. static int mnrflag;
  61. static int etrflag;
  62. void chkit(), printerr(), mnrand(), etrand(), shownoncrit();
  63. void chkid(), pvec();
  64. main()
  65. {
  66. int i, iprec;
  67. printf( "Steve Moshier's printf/scanf tester, version 0.2.\n\n" );
  68. #ifdef DEC
  69. /* DEC PDP-11/VAX single precision not yet implemented */
  70. for( iprec = 1; iprec<2; iprec++ )
  71. #else
  72. for( iprec = 0; iprec<3; iprec++ )
  73. #endif
  74. {
  75. errscan = 0;
  76. identerr = 0;
  77. errprint = 0;
  78. eclear( rprint );
  79. eclear( rscan );
  80. switch( iprec )
  81. {
  82. case 0:
  83. SPREC = 8; /* # digits after the decimal point */
  84. mprec = 24; /* # bits in the significand */
  85. m = 9; /* max # decimal digits for correct rounding */
  86. n = 13; /* max power of ten for correct rounding */
  87. k2 = -125; /* underflow beyond 2^-k2 */
  88. format = format24; /* printf format string */
  89. fformat = fformat24; /* scanf format string */
  90. mnrflag = 1; /* sets interval for random numbers */
  91. etrflag = 1;
  92. printf( "Testing FLOAT precision.\n" );
  93. break;
  94. case 1:
  95. #ifdef DEC
  96. SPREC = 17;
  97. mprec = 56;
  98. m = 17;
  99. n = 27;
  100. k2 = -125;
  101. format = format53;
  102. fformat = fformat53;
  103. mnrflag = 2;
  104. etrflag = 1;
  105. printf( "Testing DEC DOUBLE precision.\n" );
  106. break;
  107. #else
  108. SPREC = 16;
  109. mprec = 53;
  110. m = 17;
  111. n = 27;
  112. k2 = -1021;
  113. format = format53;
  114. fformat = fformat53;
  115. mnrflag = 2;
  116. etrflag = 2;
  117. printf( "Testing DOUBLE precision.\n" );
  118. break;
  119. #endif
  120. case 2:
  121. #if LDOUBLE
  122. SPREC = 20;
  123. mprec = 64;
  124. m = 20;
  125. n = 34;
  126. k2 = -16382;
  127. format = format64;
  128. fformat = fformat64;
  129. mnrflag = 3;
  130. etrflag = 3;
  131. printf( "Testing LONG DOUBLE precision.\n" );
  132. break;
  133. #else
  134. goto nodenorm;
  135. #endif
  136. }
  137. asctoe( Ten, eten );
  138. /* 10^m - 1 */
  139. d2 = m;
  140. e53toe( &d2, e1 );
  141. epow( eten, e1, maxm );
  142. esub( eone, maxm, maxm );
  143. /* test 1 */
  144. printf( "1. Checking 10^n - 1 for n = %d to %d.\n", -m, m );
  145. emov( eone, q5 );
  146. for( count=0; count<=m; count++ )
  147. {
  148. esub( eone, q5, fullp );
  149. chkit( 1 );
  150. ediv( q5, eone, q2 );
  151. esub( eone, q2, fullp );
  152. chkit( 1 );
  153. emul( eten, q5, q5 );
  154. if( errtot >= MAXERR )
  155. {
  156. printf( "%s", toomany );
  157. goto end1;
  158. }
  159. }
  160. end1:
  161. printerr();
  162. /* test 2 */
  163. printf( "2. Checking powers of 10 from 10^-%d to 10^%d.\n", n, n );
  164. emov( eone, q5 );
  165. for( count=0; count<=n; count++ )
  166. {
  167. emov( q5, fullp );
  168. chkit( 2 );
  169. ediv( q5, eone, fullp );
  170. chkit( 2 );
  171. emul( eten, q5, q5 );
  172. if( errtot >= MAXERR )
  173. {
  174. printf( "%s", toomany );
  175. goto end2;
  176. }
  177. }
  178. end2:
  179. printerr();
  180. /* test 3 */
  181. printf( "3. Checking (10^%d-1)*10^n from n = -%d to %d.\n", m, n, n );
  182. emov( eone, q5 );
  183. for( count= -n; count<=n; count++ )
  184. {
  185. emul( maxm, q5, fullp );
  186. chkit( 3 );
  187. emov( q5, fullp );
  188. ediv( fullp, eone, fullp );
  189. emul( maxm, fullp, fullp );
  190. chkit( 3 );
  191. emul( eten, q5, q5 );
  192. if( errtot >= MAXERR )
  193. {
  194. printf( "%s", toomany );
  195. goto end3;
  196. }
  197. }
  198. end3:
  199. printerr();
  200. /* test 4 */
  201. printf( "4. Checking powers of 2 from 2^-24 to 2^+56.\n" );
  202. d1 = -24.0;
  203. e53toe( &d1, q1 );
  204. epow( etwo, q1, q5 );
  205. for( count = -24; count <= 56; count++ )
  206. {
  207. emov( q5, fullp );
  208. chkit( 4 );
  209. emul( etwo, q5, q5 );
  210. if( errtot >= MAXERR )
  211. {
  212. printf( "%s", toomany );
  213. goto end4;
  214. }
  215. }
  216. end4:
  217. printerr();
  218. /* test 5 */
  219. printf( "5. Checking 2^n - 1 for n = 0 to %d.\n", mprec );
  220. emov( eone, q5 );
  221. for( count=0; count<=mprec; count++ )
  222. {
  223. esub( eone, q5, fullp );
  224. chkit( 5 );
  225. emul( etwo, q5, q5 );
  226. if( errtot >= MAXERR )
  227. {
  228. printf( "%s", toomany );
  229. goto end5;
  230. }
  231. }
  232. end5:
  233. printerr();
  234. /* test 6 */
  235. printf( "6. Checking 2^n + 1 for n = 0 to %d.\n", mprec );
  236. emov( eone, q5 );
  237. for( count=0; count<=mprec; count++ )
  238. {
  239. eadd( eone, q5, fullp );
  240. chkit( 6 );
  241. emul( etwo, q5, q5 );
  242. if( errtot >= MAXERR )
  243. {
  244. printf( "%s", toomany );
  245. goto end6;
  246. }
  247. }
  248. end6:
  249. printerr();
  250. /* test 7 */
  251. printf(
  252. "7. Checking %d values M * 10^N with random integer M and N,\n",
  253. NRAND );
  254. printf(" 1 <= M <= 10^%d - 1 and -%d <= N <= +%d.\n", m, n, n );
  255. for( i=0; i<NRAND; i++ )
  256. {
  257. mnrand( fullp );
  258. chkit( 7 );
  259. if( errtot >= MAXERR )
  260. {
  261. printf( "%s", toomany );
  262. goto end7;
  263. }
  264. }
  265. end7:
  266. printerr();
  267. /* test 8 */
  268. printf("8. Checking critical rounding cases.\n" );
  269. for( i=0; i<20; i++ )
  270. {
  271. mnrand( fullp );
  272. eabs( fullp );
  273. if( ecmp( fullp, eone ) < 0 )
  274. ediv( fullp, eone, fullp );
  275. efloor( fullp, fullp );
  276. eadd( ehalf, fullp, fullp );
  277. chkit( 8 );
  278. if( errtot >= MAXERR )
  279. {
  280. printf( "%s", toomany );
  281. goto end8;
  282. }
  283. }
  284. end8:
  285. printerr();
  286. /* test 9 */
  287. printf("9. Testing on %d random non-denormal values.\n", NRAND );
  288. for( i=0; i<NRAND; i++ )
  289. {
  290. etrand( fullp );
  291. chkit( 9 );
  292. }
  293. printerr();
  294. shownoncrit();
  295. /* test 10 */
  296. printf(
  297. "Do you want to check denormal numbers in this precision ? (y/n) " );
  298. gets( str0 );
  299. if( str0[0] != 'y' )
  300. goto nodenorm;
  301. printf( "10. Checking denormal numbers.\n" );
  302. /* Form 2^-starting power */
  303. d1 = k2;
  304. e53toe( &d1, q1 );
  305. epow( etwo, q1, e1 );
  306. /* Find 2^-mprec less than starting power */
  307. d1 = -mprec + 4;
  308. e53toe( &d1, q1 );
  309. epow( etwo, q1, e3 );
  310. emul( e1, e3, e3 );
  311. emov( e3, e2 );
  312. ediv( etwo, e2, e2 );
  313. while( ecmp(e1,e2) != 0 )
  314. {
  315. eadd( e1, e2, fullp );
  316. switch( mprec )
  317. {
  318. #if LDOUBLE
  319. case 64:
  320. etoe64( e1, &sprec64 );
  321. e64toe( &sprec64, q1 );
  322. etoe64( fullp, &prec64 );
  323. e64toe( &prec64, q2 );
  324. break;
  325. #endif
  326. #ifdef DEC
  327. case 56:
  328. #endif
  329. case 53:
  330. etoe53( e1, &sprec53 );
  331. e53toe( &sprec53, q1 );
  332. etoe53( fullp, &prec53 );
  333. e53toe( &prec53, q2 );
  334. break;
  335. case 24:
  336. etoe24( e1, &sprec24 );
  337. e24toe( &sprec24, q1 );
  338. etoe24( fullp, &prec24 );
  339. e24toe( &prec24, q2 );
  340. break;
  341. }
  342. if( ecmp( q2, ezero ) == 0 )
  343. goto maxden;
  344. chkit(10);
  345. if( ecmp(q1,q2) == 0 )
  346. {
  347. ediv( etwo, e1, e1 );
  348. emov( e3, e2 );
  349. }
  350. if( errtot >= MAXERR )
  351. {
  352. printf( "%s", toomany );
  353. goto maxden;
  354. }
  355. ediv( etwo, e2, e2 );
  356. }
  357. maxden:
  358. printerr();
  359. nodenorm:
  360. printf( "\n" );
  361. } /* loop on precision */
  362. printf( "End of test.\n" );
  363. }
  364. #if CHKINTERNAL
  365. long double xprec64;
  366. double xprec53;
  367. float xprec24;
  368. /* Check binary -> printf -> scanf -> binary identity
  369. * of internal routines
  370. */
  371. void chkinternal( ref, tst, string )
  372. unsigned short ref[], tst[];
  373. char *string;
  374. {
  375. if( ecmp(ref,tst) != 0 )
  376. {
  377. printf( "internal identity compare error!\n" );
  378. chkid( ref, tst, string );
  379. }
  380. }
  381. #endif
  382. /* Check binary -> printf -> scanf -> binary identity
  383. */
  384. void chkid( print, scan, string )
  385. unsigned short print[], scan[];
  386. char *string;
  387. {
  388. /* Test printf-scanf identity */
  389. if( ecmp( print, scan ) != 0 )
  390. {
  391. pvec( print, NE );
  392. printf( " ->printf-> %s ->scanf->\n", string );
  393. pvec( scan, NE );
  394. printf( " is not an identity.\n" );
  395. ++identerr;
  396. }
  397. }
  398. /* Check scanf result
  399. */
  400. void chkscan( ref, tst, string )
  401. unsigned short ref[], tst[];
  402. char *string;
  403. {
  404. /* Test scanf() */
  405. if( ecmp( ref, tst ) != 0 )
  406. {
  407. printf( "scanf(%s) -> ", string );
  408. pvec( tst, NE );
  409. printf( "\n should be " );
  410. pvec( ref, NE );
  411. printf( ".\n" );
  412. ++errscan;
  413. ++errtot;
  414. }
  415. }
  416. /* Test printf() result
  417. */
  418. void chkprint( ref, tst, string )
  419. unsigned short ref[], tst[];
  420. char *string;
  421. {
  422. if( ecmp(ref, tst) != 0 )
  423. {
  424. printf( "printf( ");
  425. pvec( ref, NE );
  426. printf( ") -> %s\n", string );
  427. printf( " = " );
  428. pvec( tst, NE );
  429. printf( ".\n" );
  430. ++errprint;
  431. ++errtot;
  432. }
  433. }
  434. /* Print array of n 16-bit shorts
  435. */
  436. void pvec( x, n )
  437. unsigned short x[];
  438. int n;
  439. {
  440. int i;
  441. for( i=0; i<n; i++ )
  442. {
  443. printf( "%04x ", x[i] );
  444. }
  445. }
  446. /* Measure worst case printf rounding error
  447. */
  448. void cmpprint( ref, tst )
  449. unsigned short ref[], tst[];
  450. {
  451. unsigned short e[NE];
  452. if( ecmp( ref, ezero ) != 0 )
  453. {
  454. esub( ref, tst, e );
  455. ediv( ref, e, e );
  456. eabs( e );
  457. if( ecmp( e, rprint ) > 0 )
  458. emov( e, rprint );
  459. }
  460. }
  461. /* Measure worst case scanf rounding error
  462. */
  463. void cmpscan( ref, tst )
  464. unsigned short ref[], tst[];
  465. {
  466. unsigned short er[NE];
  467. if( ecmp( ref, ezero ) != 0 )
  468. {
  469. esub( ref, tst, er );
  470. ediv( ref, er, er );
  471. eabs( er );
  472. if( ecmp( er, rscan ) > 0 )
  473. emov( er, rscan );
  474. if( ecmp( er, ehalf ) > 0 )
  475. {
  476. etoasc( tst, str1, 21 );
  477. printf( "Bad error: scanf(%s) = %s !\n", str0, str1 );
  478. }
  479. }
  480. }
  481. /* Check rounded-down decimal string output of printf
  482. */
  483. void cmptrunc( ref, tst )
  484. unsigned short ref[], tst[];
  485. {
  486. if( ecmp( ref, tst ) != 0 )
  487. {
  488. printf( "printf(%s%s%s, %s) -> %s\n", quo, tformat, quo, str1, str2 );
  489. printf( "should be %s .\n", str3 );
  490. errprint += 1;
  491. }
  492. }
  493. void shownoncrit()
  494. {
  495. etoasc( rprint, str0, 3 );
  496. printf( "Maximum relative printf error found = %s .\n", str0 );
  497. etoasc( rscan, str0, 3 );
  498. printf( "Maximum relative scanf error found = %s .\n", str0 );
  499. }
  500. /* Produce arguments and call comparison subroutines.
  501. */
  502. void chkit( testno )
  503. int testno;
  504. {
  505. unsigned short t[NE], u[NE], v[NE];
  506. int j;
  507. switch( mprec )
  508. {
  509. #if LDOUBLE
  510. case 64:
  511. etoe64( fullp, &prec64 );
  512. e64toe( &prec64, rounded );
  513. #if CHKINTERNAL
  514. e64toasc( &prec64, str1, SPREC );
  515. asctoe64( str1, &xprec64 );
  516. e64toe( &xprec64, t );
  517. chkinternal( rounded, t, str1 );
  518. #endif
  519. /* check printf and scanf */
  520. sprintf( str2, format, prec64 );
  521. sscanf( str2, fformat, &sprec64 );
  522. e64toe( &sprec64, u );
  523. chkid( rounded, u, str2 );
  524. asctoe64( str2, &ssprec64 );
  525. e64toe( &ssprec64, v );
  526. chkscan( v, u, str2 );
  527. chkprint( rounded, v, str2 );
  528. if( testno < 8 )
  529. break;
  530. /* rounding error measurement */
  531. etoasc( fullp, str0, 24 );
  532. etoe64( fullp, &ssprec64 );
  533. e64toe( &ssprec64, u );
  534. sprintf( str2, format, ssprec64 );
  535. asctoe( str2, t );
  536. cmpprint( u, t );
  537. sscanf( str0, fformat, &sprec64 );
  538. e64toe( &sprec64, t );
  539. cmpscan( fullp, t );
  540. if( testno < 8 )
  541. break;
  542. /* strings rounded to less than maximum precision */
  543. e64toasc( &ssprec64, str1, 24 );
  544. for( j=SPREC-1; j>0; j-- )
  545. {
  546. e64toasc( &ssprec64, str3, j );
  547. asctoe( str3, v );
  548. sprintf( tformat, "%s.%dLe", pct, j );
  549. sprintf( str2, tformat, ssprec64 );
  550. asctoe( str2, t );
  551. cmptrunc( v, t );
  552. }
  553. break;
  554. #endif
  555. #ifdef DEC
  556. case 56:
  557. #endif
  558. case 53:
  559. etoe53( fullp, &prec53 );
  560. e53toe( &prec53, rounded );
  561. #if CHKINTERNAL
  562. e53toasc( &prec53, str1, SPREC );
  563. asctoe53( str1, &xprec53 );
  564. e53toe( &xprec53, t );
  565. chkinternal( rounded, t, str1 );
  566. #endif
  567. sprintf( str2, format, prec53 );
  568. sscanf( str2, fformat, &sprec53 );
  569. e53toe( &sprec53, u );
  570. chkid( rounded, u, str2 );
  571. asctoe53( str2, &ssprec53 );
  572. e53toe( &ssprec53, v );
  573. chkscan( v, u, str2 );
  574. chkprint( rounded, v, str2 );
  575. if( testno < 8 )
  576. break;
  577. /* rounding error measurement */
  578. etoasc( fullp, str0, 24 );
  579. etoe53( fullp, &ssprec53 );
  580. e53toe( &ssprec53, u );
  581. sprintf( str2, format, ssprec53 );
  582. asctoe( str2, t );
  583. cmpprint( u, t );
  584. sscanf( str0, fformat, &sprec53 );
  585. e53toe( &sprec53, t );
  586. cmpscan( fullp, t );
  587. if( testno < 8 )
  588. break;
  589. e53toasc( &ssprec53, str1, 24 );
  590. for( j=SPREC-1; j>0; j-- )
  591. {
  592. e53toasc( &ssprec53, str3, j );
  593. asctoe( str3, v );
  594. sprintf( tformat, "%s.%de", pct, j );
  595. sprintf( str2, tformat, ssprec53 );
  596. asctoe( str2, t );
  597. cmptrunc( v, t );
  598. }
  599. break;
  600. case 24:
  601. etoe24( fullp, &prec24 );
  602. e24toe( &prec24, rounded );
  603. #if CHKINTERNAL
  604. e24toasc( &prec24, str1, SPREC );
  605. asctoe24( str1, &xprec24 );
  606. e24toe( &xprec24, t );
  607. chkinternal( rounded, t, str1 );
  608. #endif
  609. sprintf( str2, format, prec24 );
  610. sscanf( str2, fformat, &sprec24 );
  611. e24toe( &sprec24, u );
  612. chkid( rounded, u, str2 );
  613. asctoe24( str2, &ssprec24 );
  614. e24toe( &ssprec24, v );
  615. chkscan( v, u, str2 );
  616. chkprint( rounded, v, str2 );
  617. if( testno < 8 )
  618. break;
  619. /* rounding error measurement */
  620. etoasc( fullp, str0, 24 );
  621. etoe24( fullp, &ssprec24 );
  622. e24toe( &ssprec24, u );
  623. sprintf( str2, format, ssprec24 );
  624. asctoe( str2, t );
  625. cmpprint( u, t );
  626. sscanf( str0, fformat, &sprec24 );
  627. e24toe( &sprec24, t );
  628. cmpscan( fullp, t );
  629. /*
  630. if( testno < 8 )
  631. break;
  632. */
  633. e24toasc( &ssprec24, str1, 24 );
  634. for( j=SPREC-1; j>0; j-- )
  635. {
  636. e24toasc( &ssprec24, str3, j );
  637. asctoe( str3, v );
  638. sprintf( tformat, "%s.%de", pct, j );
  639. sprintf( str2, tformat, ssprec24 );
  640. asctoe( str2, t );
  641. cmptrunc( v, t );
  642. }
  643. break;
  644. }
  645. }
  646. void printerr()
  647. {
  648. if( (errscan == 0) && (identerr == 0) && (errprint == 0) )
  649. printf( "No errors found.\n" );
  650. else
  651. {
  652. printf( "%d binary -> decimal errors found.\n", errprint );
  653. printf( "%d decimal -> binary errors found.\n", errscan );
  654. }
  655. errscan = 0; /* reset for next test */
  656. identerr = 0;
  657. errprint = 0;
  658. errtot = 0;
  659. }
  660. /* Random number generator
  661. * in the range M * 10^N, where 1 <= M <= 10^17 - 1
  662. * and -27 <= N <= +27. Test values of M are logarithmically distributed
  663. * random integers; test values of N are uniformly distributed random integers.
  664. */
  665. static char *fwidth = "1.036163291797320557783096e1"; /* log(sqrt(10^9-1)) */
  666. static char *dwidth = "1.957197329044938830915E1"; /* log(sqrt(10^17-1)) */
  667. static char *ldwidth = "2.302585092994045684017491e1"; /* log(sqrt(10^20-1)) */
  668. static char *a13 = "13.0";
  669. static char *a27 = "27.0";
  670. static char *a34 = "34.0";
  671. static char *a10m13 = "1.0e-13";
  672. static unsigned short LOW[ NE ], WIDTH[NE], e27[NE], e10m13[NE];
  673. void mnrand( erand )
  674. unsigned short erand[];
  675. {
  676. unsigned short ea[NE], em[NE], en[NE], ex[NE];
  677. double x, a;
  678. if( mnrflag )
  679. {
  680. if( mnrflag == 3 )
  681. {
  682. asctoe( ldwidth, WIDTH );
  683. asctoe( a34, e27 );
  684. }
  685. if( mnrflag == 2 )
  686. {
  687. asctoe( dwidth, WIDTH );
  688. asctoe( a27, e27 );
  689. }
  690. if( mnrflag == 1 )
  691. {
  692. asctoe( fwidth, WIDTH );
  693. asctoe( a13, e27 );
  694. }
  695. asctoe( a10m13, e10m13 );
  696. mnrflag = 0;
  697. }
  698. drand( &x );
  699. e53toe( &x, ex ); /* x = WIDTH * ( x - 1.0 ) + LOW; */
  700. esub( eone, ex, ex );
  701. emul( WIDTH, ex, ex );
  702. eexp( ex, ex ); /* x = exp(x); */
  703. drand( &a );
  704. e53toe( &a, ea );
  705. emul( ea, ex, ea ); /* a = 1.0e-13 * x * a; */
  706. emul( e10m13, ea, ea );
  707. eabs( ea );
  708. eadd( ea, ex, ex ); /* add fuzz */
  709. emul( ex, ex, ex ); /* square it, to get range to 10^17 - 1 */
  710. efloor( ex, em ); /* this is M */
  711. /* Random power of 10 */
  712. drand( &a );
  713. e53toe( &a, ex );
  714. esub( eone, ex, ex ); /* y3 = 54.0 * ( y3 - 1.0 ) + 0.5; */
  715. emul( e27, ex, ex );
  716. eadd( ex, ex, ex );
  717. eadd( ehalf, ex, ex );
  718. efloor( ex, ex ); /* y3 = floor( y3 ) - 27.0; */
  719. esub( e27, ex, en ); /* this is N */
  720. epow( eten, en, ex );
  721. emul( ex, em, erand );
  722. }
  723. /* -ln 2^16382 */
  724. char *ldemin = "-1.1355137111933024058873097E4";
  725. char *ldewid = "2.2710274223866048117746193E4";
  726. /* -ln 2^1022 */
  727. char *demin = "-7.0839641853226410622441123E2";
  728. char *dewid = "1.4167928370645282124488225E3";
  729. /* -ln 2^125 */
  730. char *femin = "-8.6643397569993163677154015E1";
  731. char *fewid = "1.7328679513998632735430803E2";
  732. void etrand( erand )
  733. unsigned short erand[];
  734. {
  735. unsigned short ea[NE], ex[NE];
  736. double x, a;
  737. if( etrflag )
  738. {
  739. if( etrflag == 3 )
  740. {
  741. asctoe( ldemin, LOW );
  742. asctoe( ldewid, WIDTH );
  743. asctoe( a34, e27 );
  744. }
  745. if( etrflag == 2 )
  746. {
  747. asctoe( demin, LOW );
  748. asctoe( dewid, WIDTH );
  749. asctoe( a27, e27 );
  750. }
  751. if( etrflag == 1 )
  752. {
  753. asctoe( femin, LOW );
  754. asctoe( fewid, WIDTH );
  755. asctoe( a13, e27 );
  756. }
  757. asctoe( a10m13, e10m13 );
  758. etrflag = 0;
  759. }
  760. drand( &x );
  761. e53toe( &x, ex ); /* x = WIDTH * ( x - 1.0 ) + LOW; */
  762. esub( eone, ex, ex );
  763. emul( WIDTH, ex, ex );
  764. eadd( LOW, ex, ex );
  765. eexp( ex, ex ); /* x = exp(x); */
  766. /* add fuzz
  767. */
  768. drand( &a );
  769. e53toe( &a, ea );
  770. emul( ea, ex, ea ); /* a = 1.0e-13 * x * a; */
  771. emul( e10m13, ea, ea );
  772. if( ecmp( ex, ezero ) > 0 )
  773. eneg( ea );
  774. eadd( ea, ex, erand );
  775. }