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