1 /* Extended precision arithmetic functions for long double I/O.
2 * This program has been placed in the public domain.
3 */
4
5 #ifdef __GNUC__
6 #pragma GCC diagnostic ignored "-Wpragmas"
7 #pragma GCC diagnostic ignored "-Wunknown-warning-option"
8 #pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
9 #pragma GCC diagnostic ignored "-Wanalyzer-use-of-uninitialized-value"
10 #pragma GCC diagnostic ignored "-Wanalyzer-out-of-bounds"
11 #pragma GCC diagnostic ignored "-Warray-bounds"
12 #pragma GCC diagnostic ignored "-Wanalyzer-null-dereference"
13 #endif
14
15 #define _DEFAULT_SOURCE
16
17 #ifndef _USE_GDTOA
18 #include <string.h>
19 #include <stdlib.h>
20 #include "mprec.h"
21
22 /* These are the externally visible entries. */
23 /* linux name: long double _IO_strtold (char *, char **); */
24 int _ldcheck (long double *);
25 #if 0
26 void _IO_ldtostr (long double *, char *, int, int, char);
27 #endif
28
29 /* Number of 16 bit words in external x type format */
30 #define NE 10
31
32 /* Number of 16 bit words in internal format */
33 #define NI (NE+3)
34
35 /* Array offset to exponent */
36 #define E 1
37
38 /* Array offset to high guard word */
39 #define M 2
40
41 /* Number of bits of precision */
42 #define NBITS ((NI-4)*16)
43
44 /* Maximum number of decimal digits in ASCII conversion */
45 #define NDEC 1023
46 /* Use static stack buffer for up to 44 digits */
47 #define NDEC_SML 44
48
49 /* The exponent of 1.0 */
50 #define EXONE (0x3fff)
51
52 /* Maximum exponent digits - base 10 */
53 #define MAX_EXP_DIGITS 5
54
55 /* Control structure for long double conversion including rounding precision values.
56 * rndprc can be set to 80 (if NE=6), 64, 56, 53, or 24 bits.
57 */
58 typedef struct
59 {
60 int rlast;
61 int rndprc;
62 int rw;
63 int re;
64 int outexpon;
65 unsigned short rmsk;
66 unsigned short rmbit;
67 unsigned short rebit;
68 unsigned short rbit[NI];
69 unsigned short equot[NI];
70 } LDPARMS;
71
72 static void esub (const short unsigned int *a, const short unsigned int *b,
73 short unsigned int *c, LDPARMS * ldp);
74 static void emul (const short unsigned int *a, const short unsigned int *b,
75 short unsigned int *c, LDPARMS * ldp);
76 static void ediv (const short unsigned int *a, const short unsigned int *b,
77 short unsigned int *c, LDPARMS * ldp);
78 static int ecmp (const short unsigned int *a, const short unsigned int *b);
79 static int enormlz (short unsigned int *x);
80 static int eshift (short unsigned int *x, int sc);
81 static void eshup1 (register short unsigned int *x);
82 static void eshup8 (register short unsigned int *x);
83 static void eshup6 (register short unsigned int *x);
84 static void eshdn1 (register short unsigned int *x);
85 static void eshdn8 (register short unsigned int *x);
86 static void eshdn6 (register short unsigned int *x);
87 static void eneg (short unsigned int *x);
88 static void emov (register const short unsigned int *a,
89 register short unsigned int *b);
90 static void eclear (register short unsigned int *x);
91 static void einfin (register short unsigned int *x, register LDPARMS * ldp);
92 static void efloor (short unsigned int *x, short unsigned int *y,
93 LDPARMS * ldp);
94 static void etoasc (short unsigned int *x, char *string, int ndec, int ndigs,
95 int outformat, LDPARMS * ldp);
96
97 union uconv
98 {
99 unsigned short pe;
100 long double d;
101 };
102
103 #if LDBL_MANT_DIG == 24
104 static void e24toe (short unsigned int *pe, short unsigned int *y,
105 LDPARMS * ldp);
106 #elif LDBL_MANT_DIG == 53
107 static void e53toe (short unsigned int *pe, short unsigned int *y,
108 LDPARMS * ldp);
109 #elif LDBL_MANT_DIG == 64
110 static void e64toe (short unsigned int *pe, short unsigned int *y,
111 LDPARMS * ldp);
112 #else
113 static void e113toe (short unsigned int *pe, short unsigned int *y,
114 LDPARMS * ldp);
115 #endif
116
117 /* econst.c */
118 /* e type constants used by high precision check routines */
119
120 #if NE == 10
121 /* 0.0 */
122 static const unsigned short ezero[NE] = { 0x0000, 0x0000, 0x0000, 0x0000,
123 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
124 };
125
126 /* 1.0E0 */
127 static const unsigned short eone[NE] = { 0x0000, 0x0000, 0x0000, 0x0000,
128 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x3fff,
129 };
130
131 #else
132
133 /* 0.0 */
134 static const unsigned short ezero[NE] = {
135 0, 0000000, 0000000, 0000000, 0000000, 0000000,
136 };
137
138 /* 1.0E0 */
139 static const unsigned short eone[NE] = {
140 0, 0000000, 0000000, 0000000, 0100000, 0x3fff,
141 };
142
143 #endif
144
145 /* Debugging routine for displaying errors */
146 #ifdef DEBUG
147 /* Notice: the order of appearance of the following
148 * messages is bound to the error codes defined
149 * in mconf.h.
150 */
151 static const char *const ermsg[7] = {
152 "unknown", /* error code 0 */
153 "domain", /* error code 1 */
154 "singularity", /* et seq. */
155 "overflow",
156 "underflow",
157 "total loss of precision",
158 "partial loss of precision"
159 };
160
161 #define mtherr(name, code) printf( "\n%s %s error\n", name, ermsg[code] );
162 #else
163 #define mtherr(name, code)
164 #endif
165
166 /* ieee.c
167 *
168 * Extended precision IEEE binary floating point arithmetic routines
169 *
170 * Numbers are stored in C language as arrays of 16-bit unsigned
171 * short integers. The arguments of the routines are pointers to
172 * the arrays.
173 *
174 *
175 * External e type data structure, simulates Intel 8087 chip
176 * temporary real format but possibly with a larger significand:
177 *
178 * NE-1 significand words (least significant word first,
179 * most significant bit is normally set)
180 * exponent (value = EXONE for 1.0,
181 * top bit is the sign)
182 *
183 *
184 * Internal data structure of a number (a "word" is 16 bits):
185 *
186 * ei[0] sign word (0 for positive, 0xffff for negative)
187 * ei[1] biased exponent (value = EXONE for the number 1.0)
188 * ei[2] high guard word (always zero after normalization)
189 * ei[3]
190 * to ei[NI-2] significand (NI-4 significand words,
191 * most significant word first,
192 * most significant bit is set)
193 * ei[NI-1] low guard word (0x8000 bit is rounding place)
194 *
195 *
196 *
197 * Routines for external format numbers
198 *
199 * asctoe( string, e ) ASCII string to extended double e type
200 * asctoe64( string, &d ) ASCII string to long double
201 * asctoe53( string, &d ) ASCII string to double
202 * asctoe24( string, &f ) ASCII string to single
203 * asctoeg( string, e, prec, ldp ) ASCII string to specified precision
204 * e24toe( &f, e, ldp ) IEEE single precision to e type
205 * e53toe( &d, e, ldp ) IEEE double precision to e type
206 * e64toe( &d, e, ldp ) IEEE long double precision to e type
207 * e113toe( &d, e, ldp ) IEEE long double precision to e type
208 * eabs(e) absolute value
209 * eadd( a, b, c ) c = b + a
210 * eclear(e) e = 0
211 * ecmp (a, b) Returns 1 if a > b, 0 if a == b,
212 * -1 if a < b, -2 if either a or b is a NaN.
213 * ediv( a, b, c, ldp ) c = b / a
214 * efloor( a, b, ldp ) truncate to integer, toward -infinity
215 * efrexp( a, exp, s ) extract exponent and significand
216 * eifrac( e, &l, frac ) e to long integer and e type fraction
217 * euifrac( e, &l, frac ) e to unsigned long integer and e type fraction
218 * einfin( e, ldp ) set e to infinity, leaving its sign alone
219 * eldexp( a, n, b ) multiply by 2**n
220 * emov( a, b ) b = a
221 * emul( a, b, c, ldp ) c = b * a
222 * eneg(e) e = -e
223 * eround( a, b ) b = nearest integer value to a
224 * esub( a, b, c, ldp ) c = b - a
225 * e24toasc( &f, str, n ) single to ASCII string, n digits after decimal
226 * e53toasc( &d, str, n ) double to ASCII string, n digits after decimal
227 * e64toasc( &d, str, n ) long double to ASCII string
228 * etoasc(e,str,ndec,n,fmt,ldp)e to ASCII string, n digits after decimal
229 * etoe24( e, &f ) convert e type to IEEE single precision
230 * etoe53( e, &d ) convert e type to IEEE double precision
231 * etoe64( e, &d ) convert e type to IEEE long double precision
232 * ltoe( &l, e ) long (32 bit) integer to e type
233 * ultoe( &l, e ) unsigned long (32 bit) integer to e type
234 * eisneg( e ) 1 if sign bit of e != 0, else 0
235 * eisinf( e ) 1 if e has maximum exponent (non-IEEE)
236 * or is infinite (IEEE)
237 * eisnan( e ) 1 if e is a NaN
238 * esqrt( a, b ) b = square root of a
239 *
240 *
241 * Routines for internal format numbers
242 *
243 * eaddm( ai, bi ) add significands, bi = bi + ai
244 * ecleaz(ei) ei = 0
245 * ecleazs(ei) set ei = 0 but leave its sign alone
246 * ecmpm( ai, bi ) compare significands, return 1, 0, or -1
247 * edivm( ai, bi, ldp ) divide significands, bi = bi / ai
248 * emdnorm(ai,l,s,exp,ldp) normalize and round off
249 * emovi( a, ai ) convert external a to internal ai
250 * emovo( ai, a, ldp ) convert internal ai to external a
251 * emovz( ai, bi ) bi = ai, low guard word of bi = 0
252 * emulm( ai, bi, ldp ) multiply significands, bi = bi * ai
253 * enormlz(ei) left-justify the significand
254 * eshdn1( ai ) shift significand and guards down 1 bit
255 * eshdn8( ai ) shift down 8 bits
256 * eshdn6( ai ) shift down 16 bits
257 * eshift( ai, n ) shift ai n bits up (or down if n < 0)
258 * eshup1( ai ) shift significand and guards up 1 bit
259 * eshup8( ai ) shift up 8 bits
260 * eshup6( ai ) shift up 16 bits
261 * esubm( ai, bi ) subtract significands, bi = bi - ai
262 *
263 *
264 * The result is always normalized and rounded to NI-4 word precision
265 * after each arithmetic operation.
266 *
267 * Exception flags are NOT fully supported.
268 *
269 * Define USE_INFINITY in mconf.h for support of infinity; otherwise a
270 * saturation arithmetic is implemented.
271 *
272 * Define NANS for support of Not-a-Number items; otherwise the
273 * arithmetic will never produce a NaN output, and might be confused
274 * by a NaN input.
275 * If NaN's are supported, the output of ecmp(a,b) is -2 if
276 * either a or b is a NaN. This means asking if(ecmp(a,b) < 0)
277 * may not be legitimate. Use if(ecmp(a,b) == -1) for less-than
278 * if in doubt.
279 * Signaling NaN's are NOT supported; they are treated the same
280 * as quiet NaN's.
281 *
282 * Denormals are always supported here where appropriate (e.g., not
283 * for conversion to DEC numbers).
284 */
285
286 /*
287 * Revision history:
288 *
289 * 5 Jan 84 PDP-11 assembly language version
290 * 6 Dec 86 C language version
291 * 30 Aug 88 100 digit version, improved rounding
292 * 15 May 92 80-bit long double support
293 * 22 Nov 00 Revised to fit into newlib by Jeff Johnston <jjohnstn@redhat.com>
294 *
295 * Author: S. L. Moshier.
296 *
297 * Copyright (c) 1984,2000 S.L. Moshier
298 *
299 * Permission to use, copy, modify, and distribute this software for any
300 * purpose without fee is hereby granted, provided that this entire notice
301 * is included in all copies of any software which is or includes a copy
302 * or modification of this software and in all copies of the supporting
303 * documentation for such software.
304 *
305 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
306 * WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION
307 * OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
308 * SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
309 *
310 */
311
312 #include <stdio.h>
313 /* #include "\usr\include\stdio.h" */
314 /*#include "ehead.h"*/
315 /*#include "mconf.h"*/
316 /* mconf.h
317 *
318 * Common include file for math routines
319 *
320 *
321 *
322 * SYNOPSIS:
323 *
324 * #include "mconf.h"
325 *
326 *
327 *
328 * DESCRIPTION:
329 *
330 * This file contains definitions for error codes that are
331 * passed to the common error handling routine mtherr()
332 * (which see).
333 *
334 * The file also includes a conditional assembly definition
335 * for the type of computer arithmetic (IEEE, DEC, Motorola
336 * IEEE, or UNKnown).
337 *
338 * For Digital Equipment PDP-11 and VAX computers, certain
339 * IBM systems, and others that use numbers with a 56-bit
340 * significand, the symbol DEC should be defined. In this
341 * mode, most floating point constants are given as arrays
342 * of octal integers to eliminate decimal to binary conversion
343 * errors that might be introduced by the compiler.
344 *
345 * For computers, such as IBM PC, that follow the IEEE
346 * Standard for Binary Floating Point Arithmetic (ANSI/IEEE
347 * Std 754-1985), the symbol IBMPC should be defined. These
348 * numbers have 53-bit significands. In this mode, constants
349 * are provided as arrays of hexadecimal 16 bit integers.
350 *
351 * To accommodate other types of computer arithmetic, all
352 * constants are also provided in a normal decimal radix
353 * which one can hope are correctly converted to a suitable
354 * format by the available C language compiler. To invoke
355 * this mode, the symbol UNK is defined.
356 *
357 * An important difference among these modes is a predefined
358 * set of machine arithmetic constants for each. The numbers
359 * MACHEP (the machine roundoff error), MAXNUM (largest number
360 * represented), and several other parameters are preset by
361 * the configuration symbol. Check the file const.c to
362 * ensure that these values are correct for your computer.
363 *
364 * For ANSI C compatibility, define ANSIC equal to 1. Currently
365 * this affects only the atan2() function and others that use it.
366 */
367
368 /* Constant definitions for math error conditions
369 */
370
371 #define DOMAIN 1 /* argument domain error */
372 #define SING 2 /* argument singularity */
373 #define OVERFLOW 3 /* overflow range error */
374 #define UNDERFLOW 4 /* underflow range error */
375 #define TLOSS 5 /* total loss of precision */
376 #define PLOSS 6 /* partial loss of precision */
377
378 #define EDOM 33
379 #define ERANGE 34
380
381 typedef struct
382 {
383 double r;
384 double i;
385 } cmplx;
386
387 /* Type of computer arithmetic */
388
389 #ifndef DEC
390 #ifdef __IEEE_LITTLE_ENDIAN
391 #define IBMPC 1
392 #else /* !__IEEE_LITTLE_ENDIAN */
393 #define MIEEE 1
394 #endif /* !__IEEE_LITTLE_ENDIAN */
395 #endif /* !DEC */
396
397 /* Define 1 for ANSI C atan2() function
398 * See atan.c and clog.c.
399 */
400 #define ANSIC 1
401
402 /*define VOLATILE volatile*/
403 #define VOLATILE
404
405 #define NANS
406 #define USE_INFINITY
407
408 /* NaN's require infinity support. */
409 #ifdef NANS
410 #ifndef INFINITY
411 #define USE_INFINITY
412 #endif
413 #endif
414
415 /* This handles 64-bit long ints. */
416 #define LONGBITS (8 * sizeof(long))
417
418
419 static void eaddm (short unsigned int *x, short unsigned int *y);
420 static void esubm (short unsigned int *x, short unsigned int *y);
421 static void emdnorm (short unsigned int *s, int lost, int subflg,
422 long int exp, int rcntrl, LDPARMS * ldp);
423 #if 0 /* Broken, unusable implementation of strtold */
424 static int asctoeg (char *ss, short unsigned int *y, int oprec,
425 LDPARMS * ldp);
426 #endif
427 static void enan (short unsigned int *nan, int size);
428 #if LDBL_MANT_DIG == 24
429 static void toe24 (short unsigned int *x, short unsigned int *y);
430 #elif LDBL_MANT_DIG == 53
431 static void toe53 (short unsigned int *x, short unsigned int *y);
432 #elif LDBL_MANT_DIG == 64
433 static void toe64 (short unsigned int *a, short unsigned int *b);
434 #else
435 static void toe113 (short unsigned int *a, short unsigned int *b);
436 #endif
437 static void eiremain (short unsigned int *den, short unsigned int *num,
438 LDPARMS * ldp);
439 static int ecmpm (register short unsigned int *a,
440 register short unsigned int *b);
441 static int edivm (short unsigned int *den, short unsigned int *num,
442 LDPARMS * ldp);
443 static int emulm (short unsigned int *a, short unsigned int *b,
444 LDPARMS * ldp);
445 static int eisneg (const short unsigned int *x);
446 static int eisinf (const short unsigned int *x);
447 static void emovi (const short unsigned int *a, short unsigned int *b);
448 static void emovo (short unsigned int *a, short unsigned int *b,
449 LDPARMS * ldp);
450 static void emovz (register short unsigned int *a,
451 register short unsigned int *b);
452 static void ecleaz (register short unsigned int *xi);
453 static void eadd1 (const short unsigned int *a, const short unsigned int *b,
454 short unsigned int *c, int subflg, LDPARMS * ldp);
455 static int eisnan (const short unsigned int *x);
456 static int eiisnan (short unsigned int *x);
457
458 #ifdef DEC
459 static void etodec (), todec (), dectoe ();
460 #endif
461
462 /*
463 ; Clear out entire external format number.
464 ;
465 ; unsigned short x[];
466 ; eclear( x );
467 */
468
469 static void
eclear(register short unsigned int * x)470 eclear (register short unsigned int *x)
471 {
472 register int i;
473
474 for (i = 0; i < NE; i++)
475 *x++ = 0;
476 }
477
478
479
480 /* Move external format number from a to b.
481 *
482 * emov( a, b );
483 */
484
485 static void
emov(register const short unsigned int * a,register short unsigned int * b)486 emov (register const short unsigned int *a, register short unsigned int *b)
487 {
488 register int i;
489
490 for (i = 0; i < NE; i++)
491 *b++ = *a++;
492 }
493
494
495 /*
496 ; Negate external format number
497 ;
498 ; unsigned short x[NE];
499 ; eneg( x );
500 */
501
502 static void
eneg(short unsigned int * x)503 eneg (short unsigned int *x)
504 {
505
506 #ifdef NANS
507 if (eisnan (x))
508 return;
509 #endif
510 x[NE - 1] ^= 0x8000; /* Toggle the sign bit */
511 }
512
513
514
515 /* Return 1 if external format number is negative,
516 * else return zero.
517 */
518 static int
eisneg(const short unsigned int * x)519 eisneg (const short unsigned int *x)
520 {
521
522 #ifdef NANS
523 if (eisnan (x))
524 return (0);
525 #endif
526 if (x[NE - 1] & 0x8000)
527 return (1);
528 else
529 return (0);
530 }
531
532
533 /* Return 1 if external format number has maximum possible exponent,
534 * else return zero.
535 */
536 static int
eisinf(const short unsigned int * x)537 eisinf (const short unsigned int *x)
538 {
539
540 if ((x[NE - 1] & 0x7fff) == 0x7fff)
541 {
542 #ifdef NANS
543 if (eisnan (x))
544 return (0);
545 #endif
546 return (1);
547 }
548 else
549 return (0);
550 }
551
552 /* Check if e-type number is not a number.
553 */
554 static int
eisnan(const short unsigned int * x)555 eisnan (const short unsigned int *x)
556 {
557
558 #ifdef NANS
559 int i;
560 /* NaN has maximum exponent */
561 if ((x[NE - 1] & 0x7fff) != 0x7fff)
562 return (0);
563 /* ... and non-zero significand field. */
564 for (i = 0; i < NE - 1; i++)
565 {
566 if (*x++ != 0)
567 return (1);
568 }
569 #endif
570 return (0);
571 }
572
573 /*
574 ; Fill entire number, including exponent and significand, with
575 ; largest possible number. These programs implement a saturation
576 ; value that is an ordinary, legal number. A special value
577 ; "infinity" may also be implemented; this would require tests
578 ; for that value and implementation of special rules for arithmetic
579 ; operations involving inifinity.
580 */
581
582 static void
einfin(register short unsigned int * x,register LDPARMS * ldp)583 einfin (register short unsigned int *x, register LDPARMS * ldp)
584 {
585 register int i;
586
587 #ifdef USE_INFINITY
588 for (i = 0; i < NE - 1; i++)
589 *x++ = 0;
590 *x |= 32767;
591 (void) ldp;
592 #else
593 for (i = 0; i < NE - 1; i++)
594 *x++ = 0xffff;
595 *x |= 32766;
596 if (ldp->rndprc < NBITS)
597 {
598 if (ldp->rndprc == 113)
599 {
600 *(x - 9) = 0;
601 *(x - 8) = 0;
602 }
603 if (ldp->rndprc == 64)
604 {
605 *(x - 5) = 0;
606 }
607 if (ldp->rndprc == 53)
608 {
609 *(x - 4) = 0xf800;
610 }
611 else
612 {
613 *(x - 4) = 0;
614 *(x - 3) = 0;
615 *(x - 2) = 0xff00;
616 }
617 }
618 #endif
619 }
620
621 /* Move in external format number,
622 * converting it to internal format.
623 */
624 static void
emovi(const short unsigned int * a,short unsigned int * b)625 emovi (const short unsigned int *a, short unsigned int *b)
626 {
627 register const unsigned short *p;
628 register unsigned short *q;
629 int i;
630
631 q = b;
632 p = a + (NE - 1); /* point to last word of external number */
633 /* get the sign bit */
634 if (*p & 0x8000)
635 *q++ = 0xffff;
636 else
637 *q++ = 0;
638 /* get the exponent */
639 *q = *p--;
640 *q++ &= 0x7fff; /* delete the sign bit */
641 #ifdef USE_INFINITY
642 if ((*(q - 1) & 0x7fff) == 0x7fff)
643 {
644 #ifdef NANS
645 if (eisnan (a))
646 {
647 *q++ = 0;
648 for (i = 3; i < NI; i++)
649 *q++ = *p--;
650 return;
651 }
652 #endif
653 for (i = 2; i < NI; i++)
654 *q++ = 0;
655 return;
656 }
657 #endif
658 /* clear high guard word */
659 *q++ = 0;
660 /* move in the significand */
661 for (i = 0; i < NE - 1; i++)
662 *q++ = *p--;
663 /* clear low guard word */
664 *q = 0;
665 }
666
667
668 /* Move internal format number out,
669 * converting it to external format.
670 */
671 static void
emovo(short unsigned int * a,short unsigned int * b,LDPARMS * ldp)672 emovo (short unsigned int *a, short unsigned int *b, LDPARMS * ldp)
673 {
674 register unsigned short *p, *q;
675 unsigned short i;
676
677 p = a;
678 q = b + (NE - 1); /* point to output exponent */
679 /* combine sign and exponent */
680 i = *p++;
681 if (i)
682 *q-- = *p++ | 0x8000;
683 else
684 *q-- = *p++;
685 #ifdef USE_INFINITY
686 if (*(p - 1) == 0x7fff)
687 {
688 #ifdef NANS
689 if (eiisnan (a))
690 {
691 enan (b, NBITS);
692 return;
693 }
694 #endif
695 einfin (b, ldp);
696 return;
697 }
698 #endif
699 /* skip over guard word */
700 ++p;
701 /* move the significand */
702 for (i = 0; i < NE - 1; i++)
703 *q-- = *p++;
704 }
705
706
707 /* Clear out internal format number.
708 */
709
710 static void
ecleaz(register short unsigned int * xi)711 ecleaz (register short unsigned int *xi)
712 {
713 register int i;
714
715 for (i = 0; i < NI; i++)
716 *xi++ = 0;
717 }
718
719 /* same, but don't touch the sign. */
720
721 static void
ecleazs(register short unsigned int * xi)722 ecleazs (register short unsigned int *xi)
723 {
724 register int i;
725
726 ++xi;
727 for (i = 0; i < NI - 1; i++)
728 *xi++ = 0;
729 }
730
731
732
733
734 /* Move internal format number from a to b.
735 */
736 static void
emovz(register short unsigned int * a,register short unsigned int * b)737 emovz (register short unsigned int *a, register short unsigned int *b)
738 {
739 register int i;
740
741 for (i = 0; i < NI - 1; i++)
742 *b++ = *a++;
743 /* clear low guard word */
744 *b = 0;
745 }
746
747 /* Return nonzero if internal format number is a NaN.
748 */
749
750 static int
eiisnan(short unsigned int * x)751 eiisnan (short unsigned int *x)
752 {
753 int i;
754
755 if ((x[E] & 0x7fff) == 0x7fff)
756 {
757 for (i = M + 1; i < NI; i++)
758 {
759 if (x[i] != 0)
760 return (1);
761 }
762 }
763 return (0);
764 }
765
766 #if LDBL_MANT_DIG == 64
767
768 #ifdef USE_INFINITY
769 #ifdef IBMPC
770
771 /* Return nonzero if internal format number is infinite. */
772 static int
eiisinf(unsigned short x[])773 eiisinf (unsigned short x[])
774 {
775
776 #ifdef NANS
777 if (eiisnan (x))
778 return (0);
779 #endif
780 if ((x[E] & 0x7fff) == 0x7fff)
781 return (1);
782 return (0);
783 }
784 #endif
785 #endif
786
787 #endif /* LDBL_MANT_DIG == 64 */
788
789 /*
790 ; Compare significands of numbers in internal format.
791 ; Guard words are included in the comparison.
792 ;
793 ; unsigned short a[NI], b[NI];
794 ; cmpm( a, b );
795 ;
796 ; for the significands:
797 ; returns +1 if a > b
798 ; 0 if a == b
799 ; -1 if a < b
800 */
801 static int
ecmpm(register short unsigned int * a,register short unsigned int * b)802 ecmpm (register short unsigned int *a, register short unsigned int *b)
803 {
804 int i;
805
806 a += M; /* skip up to significand area */
807 b += M;
808 for (i = M; i < NI; i++)
809 {
810 if (*a++ != *b++)
811 goto difrnt;
812 }
813 return (0);
814
815 difrnt:
816 if (*(--a) > *(--b))
817 return (1);
818 else
819 return (-1);
820 }
821
822
823 /*
824 ; Shift significand down by 1 bit
825 */
826
827 static void
eshdn1(register short unsigned int * x)828 eshdn1 (register short unsigned int *x)
829 {
830 register unsigned short bits;
831 int i;
832
833 x += M; /* point to significand area */
834
835 bits = 0;
836 for (i = M; i < NI; i++)
837 {
838 if (*x & 1)
839 bits |= 1;
840 *x >>= 1;
841 if (bits & 2)
842 *x |= 0x8000;
843 bits <<= 1;
844 ++x;
845 }
846 }
847
848
849
850 /*
851 ; Shift significand up by 1 bit
852 */
853
854 static void
eshup1(register short unsigned int * x)855 eshup1 (register short unsigned int *x)
856 {
857 register unsigned short bits;
858 int i;
859
860 x += NI - 1;
861 bits = 0;
862
863 for (i = M; i < NI; i++)
864 {
865 if (*x & 0x8000)
866 bits |= 1;
867 *x <<= 1;
868 if (bits & 2)
869 *x |= 1;
870 bits <<= 1;
871 --x;
872 }
873 }
874
875
876
877 /*
878 ; Shift significand down by 8 bits
879 */
880
881 static void
eshdn8(register short unsigned int * x)882 eshdn8 (register short unsigned int *x)
883 {
884 register unsigned short newbyt, oldbyt;
885 int i;
886
887 x += M;
888 oldbyt = 0;
889 for (i = M; i < NI; i++)
890 {
891 newbyt = *x << 8;
892 *x >>= 8;
893 *x |= oldbyt;
894 oldbyt = newbyt;
895 ++x;
896 }
897 }
898
899 /*
900 ; Shift significand up by 8 bits
901 */
902
903 static void
eshup8(register short unsigned int * x)904 eshup8 (register short unsigned int *x)
905 {
906 int i;
907 register unsigned short newbyt, oldbyt;
908
909 x += NI - 1;
910 oldbyt = 0;
911
912 for (i = M; i < NI; i++)
913 {
914 newbyt = *x >> 8;
915 *x <<= 8;
916 *x |= oldbyt;
917 oldbyt = newbyt;
918 --x;
919 }
920 }
921
922 /*
923 ; Shift significand up by 16 bits
924 */
925
926 static void
eshup6(register short unsigned int * x)927 eshup6 (register short unsigned int *x)
928 {
929 int i;
930 register unsigned short *p;
931
932 p = x + M;
933 x += M + 1;
934
935 for (i = M; i < NI - 1; i++)
936 *p++ = *x++;
937
938 *p = 0;
939 }
940
941 /*
942 ; Shift significand down by 16 bits
943 */
944
945 static void
eshdn6(register short unsigned int * x)946 eshdn6 (register short unsigned int *x)
947 {
948 int i;
949 register unsigned short *p;
950
951 x += NI - 1;
952 p = x + 1;
953
954 for (i = M; i < NI - 1; i++)
955 *(--p) = *(--x);
956
957 *(--p) = 0;
958 }
959
960 /*
961 ; Add significands
962 ; x + y replaces y
963 */
964
965 static void
eaddm(short unsigned int * x,short unsigned int * y)966 eaddm (short unsigned int *x, short unsigned int *y)
967 {
968 register unsigned long a;
969 int i;
970 unsigned int carry;
971
972 x += NI - 1;
973 y += NI - 1;
974 carry = 0;
975 for (i = M; i < NI; i++)
976 {
977 a = (unsigned long) (*x) + (unsigned long) (*y) + carry;
978 if (a & 0x10000)
979 carry = 1;
980 else
981 carry = 0;
982 *y = (unsigned short) a;
983 --x;
984 --y;
985 }
986 }
987
988 /*
989 ; Subtract significands
990 ; y - x replaces y
991 */
992
993 static void
esubm(short unsigned int * x,short unsigned int * y)994 esubm (short unsigned int *x, short unsigned int *y)
995 {
996 unsigned long a;
997 int i;
998 unsigned int carry;
999
1000 x += NI - 1;
1001 y += NI - 1;
1002 carry = 0;
1003 for (i = M; i < NI; i++)
1004 {
1005 a = (unsigned long) (*y) - (unsigned long) (*x) - carry;
1006 if (a & 0x10000)
1007 carry = 1;
1008 else
1009 carry = 0;
1010 *y = (unsigned short) a;
1011 --x;
1012 --y;
1013 }
1014 }
1015
1016
1017 /* Divide significands */
1018
1019
1020 /* Multiply significand of e-type number b
1021 by 16-bit quantity a, e-type result to c. */
1022
1023 static void
m16m(short unsigned int a,short unsigned int * b,short unsigned int * c)1024 m16m (short unsigned int a, short unsigned int *b, short unsigned int *c)
1025 {
1026 register unsigned short *pp;
1027 register unsigned long carry;
1028 unsigned short *ps;
1029 unsigned short p[NI]= {0};
1030 unsigned long aa, m;
1031 int i;
1032
1033 aa = a;
1034 pp = &p[NI - 2];
1035 *pp++ = 0;
1036 *pp = 0;
1037 ps = &b[NI - 1];
1038
1039 for (i = M + 1; i < NI; i++)
1040 {
1041 if (*ps == 0)
1042 {
1043 --ps;
1044 --pp;
1045 *(pp - 1) = 0;
1046 }
1047 else
1048 {
1049 m = (unsigned long) aa **ps--;
1050 carry = (m & 0xffff) + *pp;
1051 *pp-- = (unsigned short) carry;
1052 carry = (carry >> 16) + (m >> 16) + *pp;
1053 *pp = (unsigned short) carry;
1054 *(pp - 1) = carry >> 16;
1055 }
1056 }
1057 for (i = M; i < NI; i++)
1058 c[i] = p[i];
1059 }
1060
1061
1062 /* Divide significands. Neither the numerator nor the denominator
1063 is permitted to have its high guard word nonzero. */
1064
1065
1066 static int
edivm(short unsigned int * den,short unsigned int * num,LDPARMS * ldp)1067 edivm (short unsigned int *den, short unsigned int *num, LDPARMS * ldp)
1068 {
1069 int i;
1070 register unsigned short *p;
1071 unsigned long tnum;
1072 unsigned short j, tdenm, tquot;
1073 unsigned short tprod[NI + 1];
1074 unsigned short *equot = ldp->equot;
1075
1076 p = &equot[0];
1077 *p++ = num[0];
1078 *p++ = num[1];
1079
1080 for (i = M; i < NI; i++)
1081 {
1082 *p++ = 0;
1083 }
1084 eshdn1 (num);
1085 tdenm = den[M + 1];
1086 for (i = M; i < NI; i++)
1087 {
1088 /* Find trial quotient digit (the radix is 65536). */
1089 tnum = (((unsigned long) num[M]) << 16) + num[M + 1];
1090
1091 /* Do not execute the divide instruction if it will overflow. */
1092 if ((tdenm * 0xffffUL) < tnum)
1093 tquot = 0xffff;
1094 else
1095 tquot = tnum / tdenm;
1096
1097 /* Prove that the divide worked. */
1098 /*
1099 tcheck = (unsigned long )tquot * tdenm;
1100 if( tnum - tcheck > tdenm )
1101 tquot = 0xffff;
1102 */
1103 /* Multiply denominator by trial quotient digit. */
1104 m16m (tquot, den, tprod);
1105 /* The quotient digit may have been overestimated. */
1106 if (ecmpm (tprod, num) > 0)
1107 {
1108 tquot -= 1;
1109 esubm (den, tprod);
1110 if (ecmpm (tprod, num) > 0)
1111 {
1112 tquot -= 1;
1113 esubm (den, tprod);
1114 }
1115 }
1116 /*
1117 if( ecmpm( tprod, num ) > 0 )
1118 {
1119 eshow( "tprod", tprod );
1120 eshow( "num ", num );
1121 printf( "tnum = %08lx, tden = %04x, tquot = %04x\n",
1122 tnum, den[M+1], tquot );
1123 }
1124 */
1125 esubm (tprod, num);
1126 /*
1127 if( ecmpm( num, den ) >= 0 )
1128 {
1129 eshow( "num ", num );
1130 eshow( "den ", den );
1131 printf( "tnum = %08lx, tden = %04x, tquot = %04x\n",
1132 tnum, den[M+1], tquot );
1133 }
1134 */
1135 equot[i] = tquot;
1136 eshup6 (num);
1137 }
1138 /* test for nonzero remainder after roundoff bit */
1139 p = &num[M];
1140 j = 0;
1141 for (i = M; i < NI; i++)
1142 {
1143 j |= *p++;
1144 }
1145 if (j)
1146 j = 1;
1147
1148 for (i = 0; i < NI; i++)
1149 num[i] = equot[i];
1150
1151 return ((int) j);
1152 }
1153
1154
1155
1156 /* Multiply significands */
1157 static int
emulm(short unsigned int * a,short unsigned int * b,LDPARMS * ldp)1158 emulm (short unsigned int *a, short unsigned int *b, LDPARMS * ldp)
1159 {
1160 unsigned short *p, *q;
1161 unsigned short pprod[NI] = {0};
1162 unsigned short j;
1163 int i;
1164 unsigned short *equot = ldp->equot;
1165
1166 equot[0] = b[0];
1167 equot[1] = b[1];
1168 for (i = M; i < NI; i++)
1169 equot[i] = 0;
1170
1171 j = 0;
1172 p = &a[NI - 1];
1173 q = &equot[NI - 1];
1174 for (i = M + 1; i < NI; i++)
1175 {
1176 if (*p == 0)
1177 {
1178 --p;
1179 }
1180 else
1181 {
1182 m16m (*p--, b, pprod);
1183 eaddm (pprod, equot);
1184 }
1185 j |= *q;
1186 eshdn6 (equot);
1187 }
1188
1189 for (i = 0; i < NI; i++)
1190 b[i] = equot[i];
1191
1192 /* return flag for lost nonzero bits */
1193 return ((int) j);
1194 }
1195
1196
1197 /*
1198 static void eshow(str, x)
1199 char *str;
1200 unsigned short *x;
1201 {
1202 int i;
1203
1204 printf( "%s ", str );
1205 for( i=0; i<NI; i++ )
1206 printf( "%04x ", *x++ );
1207 printf( "\n" );
1208 }
1209 */
1210
1211
1212 /*
1213 * Normalize and round off.
1214 *
1215 * The internal format number to be rounded is "s".
1216 * Input "lost" indicates whether the number is exact.
1217 * This is the so-called sticky bit.
1218 *
1219 * Input "subflg" indicates whether the number was obtained
1220 * by a subtraction operation. In that case if lost is nonzero
1221 * then the number is slightly smaller than indicated.
1222 *
1223 * Input "exp" is the biased exponent, which may be negative.
1224 * the exponent field of "s" is ignored but is replaced by
1225 * "exp" as adjusted by normalization and rounding.
1226 *
1227 * Input "rcntrl" is the rounding control.
1228 */
1229
1230
1231 static void
emdnorm(short unsigned int * s,int lost,int subflg,long int exp,int rcntrl,LDPARMS * ldp)1232 emdnorm (short unsigned int *s, int lost, int subflg, long int exp,
1233 int rcntrl, LDPARMS * ldp)
1234 {
1235 int i, j;
1236 unsigned short r;
1237
1238 /* Normalize */
1239 j = enormlz (s);
1240
1241 /* a blank significand could mean either zero or infinity. */
1242 #ifndef USE_INFINITY
1243 if (j > NBITS)
1244 {
1245 ecleazs (s);
1246 return;
1247 }
1248 #endif
1249 exp -= j;
1250 #ifndef USE_INFINITY
1251 if (exp >= 32767L)
1252 goto overf;
1253 #else
1254 if ((j > NBITS) && (exp < 32767L))
1255 {
1256 ecleazs (s);
1257 return;
1258 }
1259 #endif
1260 if (exp < 0L)
1261 {
1262 if (exp > (long) (-NBITS - 1))
1263 {
1264 j = (int) exp;
1265 i = eshift (s, j);
1266 if (i)
1267 lost = 1;
1268 }
1269 else
1270 {
1271 ecleazs (s);
1272 return;
1273 }
1274 }
1275 /* Round off, unless told not to by rcntrl. */
1276 if (rcntrl == 0)
1277 goto mdfin;
1278 /* Set up rounding parameters if the control register changed. */
1279 if (ldp->rndprc != ldp->rlast)
1280 {
1281 ecleaz (ldp->rbit);
1282 switch (ldp->rndprc)
1283 {
1284 default:
1285 case NBITS:
1286 ldp->rw = NI - 1; /* low guard word */
1287 ldp->rmsk = 0xffff;
1288 ldp->rmbit = 0x8000;
1289 ldp->rebit = 1;
1290 ldp->re = ldp->rw - 1;
1291 break;
1292 case 113:
1293 ldp->rw = 10;
1294 ldp->rmsk = 0x7fff;
1295 ldp->rmbit = 0x4000;
1296 ldp->rebit = 0x8000;
1297 ldp->re = ldp->rw;
1298 break;
1299 case 64:
1300 ldp->rw = 7;
1301 ldp->rmsk = 0xffff;
1302 ldp->rmbit = 0x8000;
1303 ldp->rebit = 1;
1304 ldp->re = ldp->rw - 1;
1305 break;
1306 /* For DEC arithmetic */
1307 case 56:
1308 ldp->rw = 6;
1309 ldp->rmsk = 0xff;
1310 ldp->rmbit = 0x80;
1311 ldp->rebit = 0x100;
1312 ldp->re = ldp->rw;
1313 break;
1314 case 53:
1315 ldp->rw = 6;
1316 ldp->rmsk = 0x7ff;
1317 ldp->rmbit = 0x0400;
1318 ldp->rebit = 0x800;
1319 ldp->re = ldp->rw;
1320 break;
1321 case 24:
1322 ldp->rw = 4;
1323 ldp->rmsk = 0xff;
1324 ldp->rmbit = 0x80;
1325 ldp->rebit = 0x100;
1326 ldp->re = ldp->rw;
1327 break;
1328 }
1329 ldp->rbit[ldp->re] = ldp->rebit;
1330 ldp->rlast = ldp->rndprc;
1331 }
1332
1333 /* Shift down 1 temporarily if the data structure has an implied
1334 * most significant bit and the number is denormal.
1335 * For rndprc = 64 or NBITS, there is no implied bit.
1336 * But Intel long double denormals lose one bit of significance even so.
1337 */
1338 #if IBMPC
1339 if ((exp <= 0) && (ldp->rndprc != NBITS))
1340 #else
1341 if ((exp <= 0) && (ldp->rndprc != 64) && (ldp->rndprc != NBITS))
1342 #endif
1343 {
1344 lost |= s[NI - 1] & 1;
1345 eshdn1 (s);
1346 }
1347 /* Clear out all bits below the rounding bit,
1348 * remembering in r if any were nonzero.
1349 */
1350 r = s[ldp->rw] & ldp->rmsk;
1351 if (ldp->rndprc < NBITS)
1352 {
1353 i = ldp->rw + 1;
1354 while (i < NI)
1355 {
1356 if (s[i])
1357 r |= 1;
1358 s[i] = 0;
1359 ++i;
1360 }
1361 }
1362 s[ldp->rw] &= ~ldp->rmsk;
1363 if ((r & ldp->rmbit) != 0)
1364 {
1365 if (r == ldp->rmbit)
1366 {
1367 if (lost == 0)
1368 { /* round to even */
1369 if ((s[ldp->re] & ldp->rebit) == 0)
1370 goto mddone;
1371 }
1372 else
1373 {
1374 if (subflg != 0)
1375 goto mddone;
1376 }
1377 }
1378 eaddm (ldp->rbit, s);
1379 }
1380 mddone:
1381 #if IBMPC
1382 if ((exp <= 0) && (ldp->rndprc != NBITS))
1383 #else
1384 if ((exp <= 0) && (ldp->rndprc != 64) && (ldp->rndprc != NBITS))
1385 #endif
1386 {
1387 eshup1 (s);
1388 }
1389 if (s[2] != 0)
1390 { /* overflow on roundoff */
1391 eshdn1 (s);
1392 exp += 1;
1393 }
1394 mdfin:
1395 s[NI - 1] = 0;
1396 if (exp >= 32767L)
1397 {
1398 #ifndef USE_INFINITY
1399 overf:
1400 #endif
1401 #ifdef USE_INFINITY
1402 s[1] = 32767;
1403 for (i = 2; i < NI - 1; i++)
1404 s[i] = 0;
1405 #else
1406 s[1] = 32766;
1407 s[2] = 0;
1408 for (i = M + 1; i < NI - 1; i++)
1409 s[i] = 0xffff;
1410 s[NI - 1] = 0;
1411 if ((ldp->rndprc < 64) || (ldp->rndprc == 113))
1412 {
1413 s[ldp->rw] &= ~ldp->rmsk;
1414 if (ldp->rndprc == 24)
1415 {
1416 s[5] = 0;
1417 s[6] = 0;
1418 }
1419 }
1420 #endif
1421 return;
1422 }
1423 if (exp < 0)
1424 s[1] = 0;
1425 else
1426 s[1] = (unsigned short) exp;
1427 }
1428
1429
1430
1431 /*
1432 ; Subtract external format numbers.
1433 ;
1434 ; unsigned short a[NE], b[NE], c[NE];
1435 ; LDPARMS *ldp;
1436 ; esub( a, b, c, ldp ); c = b - a
1437 */
1438
1439 static void
esub(const short unsigned int * a,const short unsigned int * b,short unsigned int * c,LDPARMS * ldp)1440 esub (const short unsigned int *a, const short unsigned int *b,
1441 short unsigned int *c, LDPARMS * ldp)
1442 {
1443
1444 #ifdef NANS
1445 if (eisnan (a))
1446 {
1447 emov (a, c);
1448 return;
1449 }
1450 if (eisnan (b))
1451 {
1452 emov (b, c);
1453 return;
1454 }
1455 /* Infinity minus infinity is a NaN.
1456 * Test for subtracting infinities of the same sign.
1457 */
1458 if (eisinf (a) && eisinf (b) && ((eisneg (a) ^ eisneg (b)) == 0))
1459 {
1460 mtherr ("esub", DOMAIN);
1461 enan (c, NBITS);
1462 return;
1463 }
1464 #endif
1465 eadd1 (a, b, c, 1, ldp);
1466 }
1467
1468
1469
1470 static void
eadd1(const short unsigned int * a,const short unsigned int * b,short unsigned int * c,int subflg,LDPARMS * ldp)1471 eadd1 (const short unsigned int *a, const short unsigned int *b,
1472 short unsigned int *c, int subflg, LDPARMS * ldp)
1473 {
1474 unsigned short ai[NI] = {0}, bi[NI] = {0}, ci[NI] = {0};
1475 int i, lost, j, k;
1476 long lt, lta, ltb;
1477
1478 #ifdef USE_INFINITY
1479 if (eisinf (a))
1480 {
1481 emov (a, c);
1482 if (subflg)
1483 eneg (c);
1484 return;
1485 }
1486 if (eisinf (b))
1487 {
1488 emov (b, c);
1489 return;
1490 }
1491 #endif
1492 emovi (a, ai);
1493 emovi (b, bi);
1494 if (subflg)
1495 ai[0] = ~ai[0];
1496
1497 /* compare exponents */
1498 lta = ai[E];
1499 ltb = bi[E];
1500 lt = lta - ltb;
1501 if (lt > 0L)
1502 { /* put the larger number in bi */
1503 emovz (bi, ci);
1504 emovz (ai, bi);
1505 emovz (ci, ai);
1506 ltb = bi[E];
1507 lt = -lt;
1508 }
1509 lost = 0;
1510 if (lt != 0L)
1511 {
1512 if (lt < (long) (-NBITS - 1))
1513 goto done; /* answer same as larger addend */
1514 k = (int) lt;
1515 lost = eshift (ai, k); /* shift the smaller number down */
1516 }
1517 else
1518 {
1519 /* exponents were the same, so must compare significands */
1520 i = ecmpm (ai, bi);
1521 if (i == 0)
1522 { /* the numbers are identical in magnitude */
1523 /* if different signs, result is zero */
1524 if (ai[0] != bi[0])
1525 {
1526 eclear (c);
1527 return;
1528 }
1529 /* if same sign, result is double */
1530 /* double denomalized tiny number */
1531 if ((bi[E] == 0) && ((bi[3] & 0x8000) == 0))
1532 {
1533 eshup1 (bi);
1534 goto done;
1535 }
1536 /* add 1 to exponent unless both are zero! */
1537 for (j = 1; j < NI - 1; j++)
1538 {
1539 if (bi[j] != 0)
1540 {
1541 /* This could overflow, but let emovo take care of that. */
1542 ltb += 1;
1543 break;
1544 }
1545 }
1546 bi[E] = (unsigned short) ltb;
1547 goto done;
1548 }
1549 if (i > 0)
1550 { /* put the larger number in bi */
1551 emovz (bi, ci);
1552 emovz (ai, bi);
1553 emovz (ci, ai);
1554 }
1555 }
1556 if (ai[0] == bi[0])
1557 {
1558 eaddm (ai, bi);
1559 subflg = 0;
1560 }
1561 else
1562 {
1563 esubm (ai, bi);
1564 subflg = 1;
1565 }
1566 emdnorm (bi, lost, subflg, ltb, 64, ldp);
1567
1568 done:
1569 emovo (bi, c, ldp);
1570 }
1571
1572
1573
1574 /*
1575 ; Divide.
1576 ;
1577 ; unsigned short a[NE], b[NE], c[NE];
1578 ; LDPARMS *ldp;
1579 ; ediv( a, b, c, ldp ); c = b / a
1580 */
1581 static void
ediv(const short unsigned int * a,const short unsigned int * b,short unsigned int * c,LDPARMS * ldp)1582 ediv (const short unsigned int *a, const short unsigned int *b,
1583 short unsigned int *c, LDPARMS * ldp)
1584 {
1585 unsigned short ai[NI] = {0}, bi[NI] = {0};
1586 int i;
1587 long lt, lta, ltb;
1588
1589 #ifdef NANS
1590 /* Return any NaN input. */
1591 if (eisnan (a))
1592 {
1593 emov (a, c);
1594 return;
1595 }
1596 if (eisnan (b))
1597 {
1598 emov (b, c);
1599 return;
1600 }
1601 /* Zero over zero, or infinity over infinity, is a NaN. */
1602 if (((ecmp (a, ezero) == 0) && (ecmp (b, ezero) == 0))
1603 || (eisinf (a) && eisinf (b)))
1604 {
1605 mtherr ("ediv", DOMAIN);
1606 enan (c, NBITS);
1607 return;
1608 }
1609 #endif
1610 /* Infinity over anything else is infinity. */
1611 #ifdef USE_INFINITY
1612 if (eisinf (b))
1613 {
1614 if (eisneg (a) ^ eisneg (b))
1615 *(c + (NE - 1)) = 0x8000;
1616 else
1617 *(c + (NE - 1)) = 0;
1618 einfin (c, ldp);
1619 return;
1620 }
1621 if (eisinf (a))
1622 {
1623 eclear (c);
1624 return;
1625 }
1626 #endif
1627 emovi (a, ai);
1628 emovi (b, bi);
1629 lta = ai[E];
1630 ltb = bi[E];
1631 if (bi[E] == 0)
1632 { /* See if numerator is zero. */
1633 for (i = 1; i < NI - 1; i++)
1634 {
1635 if (bi[i] != 0)
1636 {
1637 ltb -= enormlz (bi);
1638 goto dnzro1;
1639 }
1640 }
1641 eclear (c);
1642 return;
1643 }
1644 dnzro1:
1645
1646 if (ai[E] == 0)
1647 { /* possible divide by zero */
1648 for (i = 1; i < NI - 1; i++)
1649 {
1650 if (ai[i] != 0)
1651 {
1652 lta -= enormlz (ai);
1653 goto dnzro2;
1654 }
1655 }
1656 if (ai[0] == bi[0])
1657 *(c + (NE - 1)) = 0;
1658 else
1659 *(c + (NE - 1)) = 0x8000;
1660 einfin (c, ldp);
1661 mtherr ("ediv", SING);
1662 return;
1663 }
1664 dnzro2:
1665
1666 i = edivm (ai, bi, ldp);
1667 /* calculate exponent */
1668 lt = ltb - lta + EXONE;
1669 emdnorm (bi, i, 0, lt, 64, ldp);
1670 /* set the sign */
1671 if (ai[0] == bi[0])
1672 bi[0] = 0;
1673 else
1674 bi[0] = 0Xffff;
1675 emovo (bi, c, ldp);
1676 }
1677
1678
1679
1680 /*
1681 ; Multiply.
1682 ;
1683 ; unsigned short a[NE], b[NE], c[NE];
1684 ; LDPARMS *ldp
1685 ; emul( a, b, c, ldp ); c = b * a
1686 */
1687 static void
emul(const short unsigned int * a,const short unsigned int * b,short unsigned int * c,LDPARMS * ldp)1688 emul (const short unsigned int *a, const short unsigned int *b,
1689 short unsigned int *c, LDPARMS * ldp)
1690 {
1691 unsigned short ai[NI] = {0}, bi[NI] = {0};
1692 int i, j;
1693 long lt, lta, ltb;
1694
1695 #ifdef NANS
1696 /* NaN times anything is the same NaN. */
1697 if (eisnan (a))
1698 {
1699 emov (a, c);
1700 return;
1701 }
1702 if (eisnan (b))
1703 {
1704 emov (b, c);
1705 return;
1706 }
1707 /* Zero times infinity is a NaN. */
1708 if ((eisinf (a) && (ecmp (b, ezero) == 0))
1709 || (eisinf (b) && (ecmp (a, ezero) == 0)))
1710 {
1711 mtherr ("emul", DOMAIN);
1712 enan (c, NBITS);
1713 return;
1714 }
1715 #endif
1716 /* Infinity times anything else is infinity. */
1717 #ifdef USE_INFINITY
1718 if (eisinf (a) || eisinf (b))
1719 {
1720 if (eisneg (a) ^ eisneg (b))
1721 *(c + (NE - 1)) = 0x8000;
1722 else
1723 *(c + (NE - 1)) = 0;
1724 einfin (c, ldp);
1725 return;
1726 }
1727 #endif
1728 emovi (a, ai);
1729 emovi (b, bi);
1730 lta = ai[E];
1731 ltb = bi[E];
1732 if (ai[E] == 0)
1733 {
1734 for (i = 1; i < NI - 1; i++)
1735 {
1736 if (ai[i] != 0)
1737 {
1738 lta -= enormlz (ai);
1739 goto mnzer1;
1740 }
1741 }
1742 eclear (c);
1743 return;
1744 }
1745 mnzer1:
1746
1747 if (bi[E] == 0)
1748 {
1749 for (i = 1; i < NI - 1; i++)
1750 {
1751 if (bi[i] != 0)
1752 {
1753 ltb -= enormlz (bi);
1754 goto mnzer2;
1755 }
1756 }
1757 eclear (c);
1758 return;
1759 }
1760 mnzer2:
1761
1762 /* Multiply significands */
1763 j = emulm (ai, bi, ldp);
1764 /* calculate exponent */
1765 lt = lta + ltb - (EXONE - 1);
1766 emdnorm (bi, j, 0, lt, 64, ldp);
1767 /* calculate sign of product */
1768 if (ai[0] == bi[0])
1769 bi[0] = 0;
1770 else
1771 bi[0] = 0xffff;
1772 emovo (bi, c, ldp);
1773 }
1774
1775
1776
1777 #if LDBL_MANT_DIG > 64
1778 static void
e113toe(short unsigned int * pe,short unsigned int * y,LDPARMS * ldp)1779 e113toe (short unsigned int *pe, short unsigned int *y, LDPARMS * ldp)
1780 {
1781 register unsigned short r;
1782 unsigned short *e, *p;
1783 unsigned short yy[NI] = {0};
1784 int i;
1785
1786 e = pe;
1787 ecleaz (yy);
1788 #ifdef IBMPC
1789 e += 7;
1790 #endif
1791 r = *e;
1792 yy[0] = 0;
1793 if (r & 0x8000)
1794 yy[0] = 0xffff;
1795 r &= 0x7fff;
1796 #ifdef USE_INFINITY
1797 if (r == 0x7fff)
1798 {
1799 #ifdef NANS
1800 #ifdef IBMPC
1801 for (i = 0; i < 7; i++)
1802 {
1803 if (pe[i] != 0)
1804 {
1805 enan (y, NBITS);
1806 return;
1807 }
1808 }
1809 #else /* !IBMPC */
1810 for (i = 1; i < 8; i++)
1811 {
1812 if (pe[i] != 0)
1813 {
1814 enan (y, NBITS);
1815 return;
1816 }
1817 }
1818 #endif /* !IBMPC */
1819 #endif /* NANS */
1820 eclear (y);
1821 einfin (y, ldp);
1822 if (*e & 0x8000)
1823 eneg (y);
1824 return;
1825 }
1826 #endif /* INFINITY */
1827 yy[E] = r;
1828 p = &yy[M + 1];
1829 #ifdef IBMPC
1830 for (i = 0; i < 7; i++)
1831 *p++ = *(--e);
1832 #else /* IBMPC */
1833 ++e;
1834 for (i = 0; i < 7; i++)
1835 *p++ = *e++;
1836 #endif /* IBMPC */
1837 /* If denormal, remove the implied bit; else shift down 1. */
1838 if (r == 0)
1839 {
1840 yy[M] = 0;
1841 }
1842 else
1843 {
1844 yy[M] = 1;
1845 eshift (yy, -1);
1846 }
1847 emovo (yy, y, ldp);
1848 }
1849
1850 /* move out internal format to ieee long double */
1851 static void
1852 __attribute__ ((__unused__))
toe113(short unsigned int * a,short unsigned int * b)1853 toe113 (short unsigned int *a, short unsigned int *b)
1854 {
1855 register unsigned short *p, *q;
1856 unsigned short i;
1857
1858 #ifdef NANS
1859 if (eiisnan (a))
1860 {
1861 enan (b, 113);
1862 return;
1863 }
1864 #endif
1865 p = a;
1866 #ifdef MIEEE
1867 q = b;
1868 #else
1869 q = b + 7; /* point to output exponent */
1870 #endif
1871
1872 /* If not denormal, delete the implied bit. */
1873 if (a[E] != 0)
1874 {
1875 eshup1 (a);
1876 }
1877 /* combine sign and exponent */
1878 i = *p++;
1879 #ifdef MIEEE
1880 if (i)
1881 *q++ = *p++ | 0x8000;
1882 else
1883 *q++ = *p++;
1884 #else
1885 if (i)
1886 *q-- = *p++ | 0x8000;
1887 else
1888 *q-- = *p++;
1889 #endif
1890 /* skip over guard word */
1891 ++p;
1892 /* move the significand */
1893 #ifdef MIEEE
1894 for (i = 0; i < 7; i++)
1895 *q++ = *p++;
1896 #else
1897 for (i = 0; i < 7; i++)
1898 *q-- = *p++;
1899 #endif
1900 }
1901 #endif /* LDBL_MANT_DIG > 64 */
1902
1903
1904 #if LDBL_MANT_DIG == 64
1905 static void
e64toe(short unsigned int * pe,short unsigned int * y,LDPARMS * ldp)1906 e64toe (short unsigned int *pe, short unsigned int *y, LDPARMS * ldp)
1907 {
1908 unsigned short yy[NI] = {0};
1909 unsigned short *p, *q, *e;
1910 int i;
1911
1912 e = pe;
1913 p = yy;
1914
1915 for (i = 0; i < NE - 5; i++)
1916 *p++ = 0;
1917 #ifdef IBMPC
1918 for (i = 0; i < 5; i++)
1919 *p++ = *e++;
1920 #endif
1921 #ifdef DEC
1922 for (i = 0; i < 5; i++)
1923 *p++ = *e++;
1924 #endif
1925 #ifdef MIEEE
1926 p = &yy[0] + (NE - 1);
1927 *p-- = *e++;
1928 ++e; /* MIEEE skips over 2nd short */
1929 for (i = 0; i < 4; i++)
1930 *p-- = *e++;
1931 #endif
1932
1933 #ifdef IBMPC
1934 /* For Intel long double, shift denormal significand up 1
1935 -- but only if the top significand bit is zero. */
1936 if ((yy[NE - 1] & 0x7fff) == 0 && (yy[NE - 2] & 0x8000) == 0)
1937 {
1938 unsigned short temp[NI + 1];
1939 emovi (yy, temp);
1940 eshup1 (temp);
1941 emovo (temp, y, ldp);
1942 return;
1943 }
1944 #endif
1945 #ifdef USE_INFINITY
1946 /* Point to the exponent field. */
1947 p = &yy[NE - 1];
1948 if ((*p & 0x7fff) == 0x7fff)
1949 {
1950 #ifdef NANS
1951 #ifdef IBMPC
1952 for (i = 0; i < 4; i++)
1953 {
1954 if ((i != 3 && pe[i] != 0)
1955 /* Check for Intel long double infinity pattern. */
1956 || (i == 3 && pe[i] != 0x8000))
1957 {
1958 enan (y, NBITS);
1959 return;
1960 }
1961 }
1962 #endif
1963 #ifdef MIEEE
1964 for (i = 2; i <= 5; i++)
1965 {
1966 if (pe[i] != 0)
1967 {
1968 enan (y, NBITS);
1969 return;
1970 }
1971 }
1972 #endif
1973 #endif /* NANS */
1974 eclear (y);
1975 einfin (y, ldp);
1976 if (*p & 0x8000)
1977 eneg (y);
1978 return;
1979 }
1980 #endif /* USE_INFINITY */
1981 p = yy;
1982 q = y;
1983 for (i = 0; i < NE; i++)
1984 *q++ = *p++;
1985 }
1986
1987 /* move out internal format to ieee long double */
1988 static void
1989 __attribute__ ((__unused__))
toe64(short unsigned int * a,short unsigned int * b)1990 toe64 (short unsigned int *a, short unsigned int *b)
1991 {
1992 register unsigned short *p, *q;
1993 unsigned short i;
1994
1995 #ifdef NANS
1996 if (eiisnan (a))
1997 {
1998 enan (b, 64);
1999 return;
2000 }
2001 #endif
2002 #ifdef IBMPC
2003 /* Shift Intel denormal significand down 1. */
2004 if (a[E] == 0)
2005 eshdn1 (a);
2006 #endif
2007 p = a;
2008 #ifdef MIEEE
2009 q = b;
2010 #else
2011 q = b + 4; /* point to output exponent */
2012 /* NOTE: Intel data type is 96 bits wide, clear the last word here. */
2013 *(q + 1) = 0;
2014 #endif
2015
2016 /* combine sign and exponent */
2017 i = *p++;
2018 #ifdef MIEEE
2019 if (i)
2020 *q++ = *p++ | 0x8000;
2021 else
2022 *q++ = *p++;
2023 *q++ = 0; /* leave 2nd short blank */
2024 #else
2025 if (i)
2026 *q-- = *p++ | 0x8000;
2027 else
2028 *q-- = *p++;
2029 #endif
2030 /* skip over guard word */
2031 ++p;
2032 /* move the significand */
2033 #ifdef MIEEE
2034 for (i = 0; i < 4; i++)
2035 *q++ = *p++;
2036 #else
2037 #ifdef USE_INFINITY
2038 #ifdef IBMPC
2039 if (eiisinf (a))
2040 {
2041 /* Intel long double infinity. */
2042 *q-- = 0x8000;
2043 *q-- = 0;
2044 *q-- = 0;
2045 *q = 0;
2046 return;
2047 }
2048 #endif /* IBMPC */
2049 #endif /* USE_INFINITY */
2050 for (i = 0; i < 4; i++)
2051 *q-- = *p++;
2052 #endif
2053 }
2054
2055 #endif /* LDBL_MANT_DIG == 64 */
2056
2057 #if LDBL_MANT_DIG == 53
2058 /*
2059 ; Convert IEEE double precision to e type
2060 ; double d;
2061 ; unsigned short x[N+2];
2062 ; e53toe( &d, x );
2063 */
2064 static void
e53toe(short unsigned int * pe,short unsigned int * y,LDPARMS * ldp)2065 e53toe (short unsigned int *pe, short unsigned int *y, LDPARMS * ldp)
2066 {
2067 #ifdef DEC
2068
2069 dectoe (pe, y); /* see etodec.c */
2070
2071 #else
2072
2073 register unsigned short r;
2074 register unsigned short *p, *e;
2075 unsigned short yy[NI] = {0};
2076 int denorm, k;
2077
2078 e = pe;
2079 denorm = 0; /* flag if denormalized number */
2080 ecleaz (yy);
2081 #ifdef IBMPC
2082 e += 3;
2083 #endif
2084 #ifdef DEC
2085 e += 3;
2086 #endif
2087 r = *e;
2088 yy[0] = 0;
2089 if (r & 0x8000)
2090 yy[0] = 0xffff;
2091 yy[M] = (r & 0x0f) | 0x10;
2092 r &= ~0x800f; /* strip sign and 4 significand bits */
2093 #ifdef USE_INFINITY
2094 if (r == 0x7ff0)
2095 {
2096 #ifdef NANS
2097 #ifdef IBMPC
2098 if (((pe[3] & 0xf) != 0) || (pe[2] != 0)
2099 || (pe[1] != 0) || (pe[0] != 0))
2100 {
2101 enan (y, NBITS);
2102 return;
2103 }
2104 #else /* !IBMPC */
2105 if (((pe[0] & 0xf) != 0) || (pe[1] != 0)
2106 || (pe[2] != 0) || (pe[3] != 0))
2107 {
2108 enan (y, NBITS);
2109 return;
2110 }
2111 #endif /* !IBMPC */
2112 #endif /* NANS */
2113 eclear (y);
2114 einfin (y, ldp);
2115 if (yy[0])
2116 eneg (y);
2117 return;
2118 }
2119 #endif
2120 r >>= 4;
2121 /* If zero exponent, then the significand is denormalized.
2122 * So, take back the understood high significand bit. */
2123 if (r == 0)
2124 {
2125 denorm = 1;
2126 yy[M] &= ~0x10;
2127 }
2128 r += EXONE - 01777;
2129 yy[E] = r;
2130 p = &yy[M + 1];
2131 #ifdef IBMPC
2132 *p++ = *(--e);
2133 *p++ = *(--e);
2134 *p++ = *(--e);
2135 #else /* !IBMPC */
2136 ++e;
2137 *p++ = *e++;
2138 *p++ = *e++;
2139 *p++ = *e++;
2140 #endif /* !IBMPC */
2141 (void) eshift (yy, -5);
2142 if (denorm)
2143 { /* if zero exponent, then normalize the significand */
2144 if ((k = enormlz (yy)) > NBITS)
2145 ecleazs (yy);
2146 else
2147 yy[E] -= (unsigned short) (k - 1);
2148 }
2149 emovo (yy, y, ldp);
2150 #endif /* !DEC */
2151 }
2152
2153 /*
2154 ; e type to IEEE double precision
2155 ; double d;
2156 ; unsigned short x[NE];
2157 ; etoe53( x, &d );
2158 */
2159
2160 #ifdef DEC
2161
2162 static void
etoe53(x,e)2163 etoe53 (x, e)
2164 unsigned short *x, *e;
2165 {
2166 etodec (x, e); /* see etodec.c */
2167 }
2168
2169 static void
2170 __attribute__ ((__unused__))
toe53(x,y)2171 toe53 (x, y)
2172 unsigned short *x, *y;
2173 {
2174 todec (x, y);
2175 }
2176
2177 #else
2178
2179 static void
2180 __attribute__ ((__unused__))
toe53(short unsigned int * x,short unsigned int * y)2181 toe53 (short unsigned int *x, short unsigned int *y)
2182 {
2183 unsigned short i;
2184 unsigned short *p;
2185
2186
2187 #ifdef NANS
2188 if (eiisnan (x))
2189 {
2190 enan (y, 53);
2191 return;
2192 }
2193 #endif
2194 p = &x[0];
2195 #ifdef IBMPC
2196 y += 3;
2197 #endif
2198 #ifdef DEC
2199 y += 3;
2200 #endif
2201 *y = 0; /* output high order */
2202 if (*p++)
2203 *y = 0x8000; /* output sign bit */
2204
2205 i = *p++;
2206 if (i >= (unsigned int) 2047)
2207 { /* Saturate at largest number less than infinity. */
2208 #ifdef USE_INFINITY
2209 *y |= 0x7ff0;
2210 #ifdef IBMPC
2211 *(--y) = 0;
2212 *(--y) = 0;
2213 *(--y) = 0;
2214 #else /* !IBMPC */
2215 ++y;
2216 *y++ = 0;
2217 *y++ = 0;
2218 *y++ = 0;
2219 #endif /* IBMPC */
2220 #else /* !USE_INFINITY */
2221 *y |= (unsigned short) 0x7fef;
2222 #ifdef IBMPC
2223 *(--y) = 0xffff;
2224 *(--y) = 0xffff;
2225 *(--y) = 0xffff;
2226 #else /* !IBMPC */
2227 ++y;
2228 *y++ = 0xffff;
2229 *y++ = 0xffff;
2230 *y++ = 0xffff;
2231 #endif
2232 #endif /* !USE_INFINITY */
2233 return;
2234 }
2235 if (i == 0)
2236 {
2237 (void) eshift (x, 4);
2238 }
2239 else
2240 {
2241 i <<= 4;
2242 (void) eshift (x, 5);
2243 }
2244 i |= *p++ & (unsigned short) 0x0f; /* *p = xi[M] */
2245 *y |= (unsigned short) i; /* high order output already has sign bit set */
2246 #ifdef IBMPC
2247 *(--y) = *p++;
2248 *(--y) = *p++;
2249 *(--y) = *p;
2250 #else /* !IBMPC */
2251 ++y;
2252 *y++ = *p++;
2253 *y++ = *p++;
2254 *y++ = *p++;
2255 #endif /* !IBMPC */
2256 }
2257
2258 #endif /* not DEC */
2259 #endif /* LDBL_MANT_DIG == 53 */
2260
2261 #if LDBL_MANT_DIG == 24
2262 /*
2263 ; Convert IEEE single precision to e type
2264 ; float d;
2265 ; unsigned short x[N+2];
2266 ; dtox( &d, x );
2267 */
2268 void
e24toe(short unsigned int * pe,short unsigned int * y,LDPARMS * ldp)2269 e24toe (short unsigned int *pe, short unsigned int *y, LDPARMS * ldp)
2270 {
2271 register unsigned short r;
2272 register unsigned short *p, *e;
2273 unsigned short yy[NI] = {0};
2274 int denorm, k;
2275
2276 e = pe;
2277 denorm = 0; /* flag if denormalized number */
2278 ecleaz (yy);
2279 #ifdef IBMPC
2280 e += 1;
2281 #endif
2282 #ifdef DEC
2283 e += 1;
2284 #endif
2285 r = *e;
2286 yy[0] = 0;
2287 if (r & 0x8000)
2288 yy[0] = 0xffff;
2289 yy[M] = (r & 0x7f) | 0200;
2290 r &= ~0x807f; /* strip sign and 7 significand bits */
2291 #ifdef USE_INFINITY
2292 if (r == 0x7f80)
2293 {
2294 #ifdef NANS
2295 #ifdef MIEEE
2296 if (((pe[0] & 0x7f) != 0) || (pe[1] != 0))
2297 {
2298 enan (y, NBITS);
2299 return;
2300 }
2301 #else /* !MIEEE */
2302 if (((pe[1] & 0x7f) != 0) || (pe[0] != 0))
2303 {
2304 enan (y, NBITS);
2305 return;
2306 }
2307 #endif /* !MIEEE */
2308 #endif /* NANS */
2309 eclear (y);
2310 einfin (y, ldp);
2311 if (yy[0])
2312 eneg (y);
2313 return;
2314 }
2315 #endif
2316 r >>= 7;
2317 /* If zero exponent, then the significand is denormalized.
2318 * So, take back the understood high significand bit. */
2319 if (r == 0)
2320 {
2321 denorm = 1;
2322 yy[M] &= ~0200;
2323 }
2324 r += EXONE - 0177;
2325 yy[E] = r;
2326 p = &yy[M + 1];
2327 #ifdef IBMPC
2328 *p++ = *(--e);
2329 #endif
2330 #ifdef DEC
2331 *p++ = *(--e);
2332 #endif
2333 #ifdef MIEEE
2334 ++e;
2335 *p++ = *e++;
2336 #endif
2337 (void) eshift (yy, -8);
2338 if (denorm)
2339 { /* if zero exponent, then normalize the significand */
2340 if ((k = enormlz (yy)) > NBITS)
2341 ecleazs (yy);
2342 else
2343 yy[E] -= (unsigned short) (k - 1);
2344 }
2345 emovo (yy, y, ldp);
2346 }
2347
2348 static void
2349 __attribute__ ((__unused__))
toe24(short unsigned int * x,short unsigned int * y)2350 toe24 (short unsigned int *x, short unsigned int *y)
2351 {
2352 unsigned short i;
2353 unsigned short *p;
2354
2355 #ifdef NANS
2356 if (eiisnan (x))
2357 {
2358 enan (y, 24);
2359 return;
2360 }
2361 #endif
2362 p = &x[0];
2363 #ifdef IBMPC
2364 y += 1;
2365 #endif
2366 #ifdef DEC
2367 y += 1;
2368 #endif
2369 *y = 0; /* output high order */
2370 if (*p++)
2371 *y = 0x8000; /* output sign bit */
2372
2373 i = *p++;
2374 if (i >= 255)
2375 { /* Saturate at largest number less than infinity. */
2376 #ifdef USE_INFINITY
2377 *y |= (unsigned short) 0x7f80;
2378 #ifdef IBMPC
2379 *(--y) = 0;
2380 #endif
2381 #ifdef DEC
2382 *(--y) = 0;
2383 #endif
2384 #ifdef MIEEE
2385 ++y;
2386 *y = 0;
2387 #endif
2388 #else /* !USE_INFINITY */
2389 *y |= (unsigned short) 0x7f7f;
2390 #ifdef IBMPC
2391 *(--y) = 0xffff;
2392 #endif
2393 #ifdef DEC
2394 *(--y) = 0xffff;
2395 #endif
2396 #ifdef MIEEE
2397 ++y;
2398 *y = 0xffff;
2399 #endif
2400 #endif /* !USE_INFINITY */
2401 return;
2402 }
2403 if (i == 0)
2404 {
2405 (void) eshift (x, 7);
2406 }
2407 else
2408 {
2409 i <<= 7;
2410 (void) eshift (x, 8);
2411 }
2412 i |= *p++ & (unsigned short) 0x7f; /* *p = xi[M] */
2413 *y |= i; /* high order output already has sign bit set */
2414 #ifdef IBMPC
2415 *(--y) = *p;
2416 #endif
2417 #ifdef DEC
2418 *(--y) = *p;
2419 #endif
2420 #ifdef MIEEE
2421 ++y;
2422 *y = *p;
2423 #endif
2424 }
2425 #endif /* LDBL_MANT_DIG == 24 */
2426
2427 /* Compare two e type numbers.
2428 *
2429 * unsigned short a[NE], b[NE];
2430 * ecmp( a, b );
2431 *
2432 * returns +1 if a > b
2433 * 0 if a == b
2434 * -1 if a < b
2435 * -2 if either a or b is a NaN.
2436 */
2437 static int
ecmp(const short unsigned int * a,const short unsigned int * b)2438 ecmp (const short unsigned int *a, const short unsigned int *b)
2439 {
2440 unsigned short ai[NI] = {0}, bi[NI] = {0};
2441 register unsigned short *p, *q;
2442 register int i;
2443 int msign;
2444
2445 #ifdef NANS
2446 if (eisnan (a) || eisnan (b))
2447 return (-2);
2448 #endif
2449 emovi (a, ai);
2450 p = ai;
2451 emovi (b, bi);
2452 q = bi;
2453
2454 if (*p != *q)
2455 { /* the signs are different */
2456 /* -0 equals + 0 */
2457 for (i = 1; i < NI - 1; i++)
2458 {
2459 if (ai[i] != 0)
2460 goto nzro;
2461 if (bi[i] != 0)
2462 goto nzro;
2463 }
2464 return (0);
2465 nzro:
2466 if (*p == 0)
2467 return (1);
2468 else
2469 return (-1);
2470 }
2471 /* both are the same sign */
2472 if (*p == 0)
2473 msign = 1;
2474 else
2475 msign = -1;
2476 i = NI - 1;
2477 do
2478 {
2479 if (*p++ != *q++)
2480 {
2481 goto diff;
2482 }
2483 }
2484 while (--i > 0);
2485
2486 return (0); /* equality */
2487
2488
2489
2490 diff:
2491
2492 if (*(--p) > *(--q))
2493 return (msign); /* p is bigger */
2494 else
2495 return (-msign); /* p is littler */
2496 }
2497
2498
2499 /*
2500 ; Shift significand
2501 ;
2502 ; Shifts significand area up or down by the number of bits
2503 ; given by the variable sc.
2504 */
2505 static int
eshift(short unsigned int * x,int sc)2506 eshift (short unsigned int *x, int sc)
2507 {
2508 unsigned short lost;
2509 unsigned short *p;
2510
2511 if (sc == 0)
2512 return (0);
2513
2514 lost = 0;
2515 p = x + NI - 1;
2516
2517 if (sc < 0)
2518 {
2519 sc = -sc;
2520 while (sc >= 16)
2521 {
2522 lost |= *p; /* remember lost bits */
2523 eshdn6 (x);
2524 sc -= 16;
2525 }
2526
2527 while (sc >= 8)
2528 {
2529 lost |= *p & 0xff;
2530 eshdn8 (x);
2531 sc -= 8;
2532 }
2533
2534 while (sc > 0)
2535 {
2536 lost |= *p & 1;
2537 eshdn1 (x);
2538 sc -= 1;
2539 }
2540 }
2541 else
2542 {
2543 while (sc >= 16)
2544 {
2545 eshup6 (x);
2546 sc -= 16;
2547 }
2548
2549 while (sc >= 8)
2550 {
2551 eshup8 (x);
2552 sc -= 8;
2553 }
2554
2555 while (sc > 0)
2556 {
2557 eshup1 (x);
2558 sc -= 1;
2559 }
2560 }
2561 if (lost)
2562 lost = 1;
2563 return ((int) lost);
2564 }
2565
2566
2567
2568 /*
2569 ; normalize
2570 ;
2571 ; Shift normalizes the significand area pointed to by argument
2572 ; shift count (up = positive) is returned.
2573 */
2574 static int
enormlz(short unsigned int * x)2575 enormlz (short unsigned int *x)
2576 {
2577 register unsigned short *p;
2578 int sc;
2579
2580 sc = 0;
2581 p = &x[M];
2582 if (*p != 0)
2583 goto normdn;
2584 ++p;
2585 if (*p & 0x8000)
2586 return (0); /* already normalized */
2587 while (*p == 0)
2588 {
2589 eshup6 (x);
2590 sc += 16;
2591 /* With guard word, there are NBITS+16 bits available.
2592 * return true if all are zero.
2593 */
2594 if (sc > NBITS)
2595 return (sc);
2596 }
2597 /* see if high byte is zero */
2598 while ((*p & 0xff00) == 0)
2599 {
2600 eshup8 (x);
2601 sc += 8;
2602 }
2603 /* now shift 1 bit at a time */
2604 while ((*p & 0x8000) == 0)
2605 {
2606 eshup1 (x);
2607 sc += 1;
2608 if (sc > (NBITS + 16))
2609 {
2610 mtherr ("enormlz", UNDERFLOW);
2611 return (sc);
2612 }
2613 }
2614 return (sc);
2615
2616 /* Normalize by shifting down out of the high guard word
2617 of the significand */
2618 normdn:
2619
2620 if (*p & 0xff00)
2621 {
2622 eshdn8 (x);
2623 sc -= 8;
2624 }
2625 while (*p != 0)
2626 {
2627 eshdn1 (x);
2628 sc -= 1;
2629
2630 if (sc < -NBITS)
2631 {
2632 mtherr ("enormlz", OVERFLOW);
2633 return (sc);
2634 }
2635 }
2636 return (sc);
2637 }
2638
2639
2640
2641
2642 /* Convert e type number to decimal format ASCII string.
2643 * The constants are for 64 bit precision.
2644 */
2645
2646 #define NTEN 12
2647 #define MAXP 4096
2648
2649 #if NE == 10
2650 static const unsigned short etens[NTEN + 1][NE] = {
2651 {0x6576, 0x4a92, 0x804a, 0x153f,
2652 0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,}, /* 10**4096 */
2653 {0x6a32, 0xce52, 0x329a, 0x28ce,
2654 0xa74d, 0x5de4, 0xc53d, 0x3b5d, 0x9e8b, 0x5a92,}, /* 10**2048 */
2655 {0x526c, 0x50ce, 0xf18b, 0x3d28,
2656 0x650d, 0x0c17, 0x8175, 0x7586, 0xc976, 0x4d48,},
2657 {0x9c66, 0x58f8, 0xbc50, 0x5c54,
2658 0xcc65, 0x91c6, 0xa60e, 0xa0ae, 0xe319, 0x46a3,},
2659 {0x851e, 0xeab7, 0x98fe, 0x901b,
2660 0xddbb, 0xde8d, 0x9df9, 0xebfb, 0xaa7e, 0x4351,},
2661 {0x0235, 0x0137, 0x36b1, 0x336c,
2662 0xc66f, 0x8cdf, 0x80e9, 0x47c9, 0x93ba, 0x41a8,},
2663 {0x50f8, 0x25fb, 0xc76b, 0x6b71,
2664 0x3cbf, 0xa6d5, 0xffcf, 0x1f49, 0xc278, 0x40d3,},
2665 {0x0000, 0x0000, 0x0000, 0x0000,
2666 0xf020, 0xb59d, 0x2b70, 0xada8, 0x9dc5, 0x4069,},
2667 {0x0000, 0x0000, 0x0000, 0x0000,
2668 0x0000, 0x0000, 0x0400, 0xc9bf, 0x8e1b, 0x4034,},
2669 {0x0000, 0x0000, 0x0000, 0x0000,
2670 0x0000, 0x0000, 0x0000, 0x2000, 0xbebc, 0x4019,},
2671 {0x0000, 0x0000, 0x0000, 0x0000,
2672 0x0000, 0x0000, 0x0000, 0x0000, 0x9c40, 0x400c,},
2673 {0x0000, 0x0000, 0x0000, 0x0000,
2674 0x0000, 0x0000, 0x0000, 0x0000, 0xc800, 0x4005,},
2675 {0x0000, 0x0000, 0x0000, 0x0000,
2676 0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,}, /* 10**1 */
2677 };
2678
2679 static const unsigned short emtens[NTEN + 1][NE] = {
2680 {0x2030, 0xcffc, 0xa1c3, 0x8123,
2681 0x2de3, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,}, /* 10**-4096 */
2682 {0x8264, 0xd2cb, 0xf2ea, 0x12d4,
2683 0x4925, 0x2de4, 0x3436, 0x534f, 0xceae, 0x256b,}, /* 10**-2048 */
2684 {0xf53f, 0xf698, 0x6bd3, 0x0158,
2685 0x87a6, 0xc0bd, 0xda57, 0x82a5, 0xa2a6, 0x32b5,},
2686 {0xe731, 0x04d4, 0xe3f2, 0xd332,
2687 0x7132, 0xd21c, 0xdb23, 0xee32, 0x9049, 0x395a,},
2688 {0xa23e, 0x5308, 0xfefb, 0x1155,
2689 0xfa91, 0x1939, 0x637a, 0x4325, 0xc031, 0x3cac,},
2690 {0xe26d, 0xdbde, 0xd05d, 0xb3f6,
2691 0xac7c, 0xe4a0, 0x64bc, 0x467c, 0xddd0, 0x3e55,},
2692 {0x2a20, 0x6224, 0x47b3, 0x98d7,
2693 0x3f23, 0xe9a5, 0xa539, 0xea27, 0xa87f, 0x3f2a,},
2694 {0x0b5b, 0x4af2, 0xa581, 0x18ed,
2695 0x67de, 0x94ba, 0x4539, 0x1ead, 0xcfb1, 0x3f94,},
2696 {0xbf71, 0xa9b3, 0x7989, 0xbe68,
2697 0x4c2e, 0xe15b, 0xc44d, 0x94be, 0xe695, 0x3fc9,},
2698 {0x3d4d, 0x7c3d, 0x36ba, 0x0d2b,
2699 0xfdc2, 0xcefc, 0x8461, 0x7711, 0xabcc, 0x3fe4,},
2700 {0xc155, 0xa4a8, 0x404e, 0x6113,
2701 0xd3c3, 0x652b, 0xe219, 0x1758, 0xd1b7, 0x3ff1,},
2702 {0xd70a, 0x70a3, 0x0a3d, 0xa3d7,
2703 0x3d70, 0xd70a, 0x70a3, 0x0a3d, 0xa3d7, 0x3ff8,},
2704 {0xcccd, 0xcccc, 0xcccc, 0xcccc,
2705 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3ffb,}, /* 10**-1 */
2706 };
2707 #else
2708 static const unsigned short etens[NTEN + 1][NE] = {
2709 {0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,}, /* 10**4096 */
2710 {0xa74d, 0x5de4, 0xc53d, 0x3b5d, 0x9e8b, 0x5a92,}, /* 10**2048 */
2711 {0x650d, 0x0c17, 0x8175, 0x7586, 0xc976, 0x4d48,},
2712 {0xcc65, 0x91c6, 0xa60e, 0xa0ae, 0xe319, 0x46a3,},
2713 {0xddbc, 0xde8d, 0x9df9, 0xebfb, 0xaa7e, 0x4351,},
2714 {0xc66f, 0x8cdf, 0x80e9, 0x47c9, 0x93ba, 0x41a8,},
2715 {0x3cbf, 0xa6d5, 0xffcf, 0x1f49, 0xc278, 0x40d3,},
2716 {0xf020, 0xb59d, 0x2b70, 0xada8, 0x9dc5, 0x4069,},
2717 {0x0000, 0x0000, 0x0400, 0xc9bf, 0x8e1b, 0x4034,},
2718 {0x0000, 0x0000, 0x0000, 0x2000, 0xbebc, 0x4019,},
2719 {0x0000, 0x0000, 0x0000, 0x0000, 0x9c40, 0x400c,},
2720 {0x0000, 0x0000, 0x0000, 0x0000, 0xc800, 0x4005,},
2721 {0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,}, /* 10**1 */
2722 };
2723
2724 static const unsigned short emtens[NTEN + 1][NE] = {
2725 {0x2de4, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,}, /* 10**-4096 */
2726 {0x4925, 0x2de4, 0x3436, 0x534f, 0xceae, 0x256b,}, /* 10**-2048 */
2727 {0x87a6, 0xc0bd, 0xda57, 0x82a5, 0xa2a6, 0x32b5,},
2728 {0x7133, 0xd21c, 0xdb23, 0xee32, 0x9049, 0x395a,},
2729 {0xfa91, 0x1939, 0x637a, 0x4325, 0xc031, 0x3cac,},
2730 {0xac7d, 0xe4a0, 0x64bc, 0x467c, 0xddd0, 0x3e55,},
2731 {0x3f24, 0xe9a5, 0xa539, 0xea27, 0xa87f, 0x3f2a,},
2732 {0x67de, 0x94ba, 0x4539, 0x1ead, 0xcfb1, 0x3f94,},
2733 {0x4c2f, 0xe15b, 0xc44d, 0x94be, 0xe695, 0x3fc9,},
2734 {0xfdc2, 0xcefc, 0x8461, 0x7711, 0xabcc, 0x3fe4,},
2735 {0xd3c3, 0x652b, 0xe219, 0x1758, 0xd1b7, 0x3ff1,},
2736 {0x3d71, 0xd70a, 0x70a3, 0x0a3d, 0xa3d7, 0x3ff8,},
2737 {0xcccd, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3ffb,}, /* 10**-1 */
2738 };
2739 #endif
2740
2741
2742
2743 /* ASCII string outputs for unix */
2744
2745
2746 #if 0
2747 void
2748 _IO_ldtostr (x, string, ndigs, flags, fmt)
2749 long double *x;
2750 char *string;
2751 int ndigs;
2752 int flags;
2753 char fmt;
2754 {
2755 unsigned short w[NI] = {0};
2756 char *t, *u;
2757 LDPARMS rnd;
2758 LDPARMS *ldp = &rnd;
2759
2760 rnd.rlast = -1;
2761 rnd.rndprc = NBITS;
2762
2763 if (sizeof (long double) == 16)
2764 e113toe ((unsigned short *) x, w, ldp);
2765 else
2766 e64toe ((unsigned short *) x, w, ldp);
2767
2768 etoasc (w, string, ndigs, -1, ldp);
2769 if (ndigs == 0 && flags == 0)
2770 {
2771 /* Delete the decimal point unless alternate format. */
2772 t = string;
2773 while (*t != '.')
2774 ++t;
2775 u = t + 1;
2776 while (*t != '\0')
2777 *t++ = *u++;
2778 }
2779 if (*string == ' ')
2780 {
2781 t = string;
2782 u = t + 1;
2783 while (*t != '\0')
2784 *t++ = *u++;
2785 }
2786 if (fmt == 'E')
2787 {
2788 t = string;
2789 while (*t != 'e')
2790 ++t;
2791 *t = 'E';
2792 }
2793 }
2794
2795 #endif
2796
2797 /* This routine will not return more than NDEC+1 digits. */
2798
2799 char *
__ldtoa(long double d,int mode,int ndigits,int * decpt,int * sign,char ** rve)2800 __ldtoa (long double d, int mode, int ndigits,
2801 int *decpt, int *sign, char **rve)
2802 {
2803 unsigned short e[NI] = {0};
2804 char *s, *p;
2805 int i, k;
2806 int orig_ndigits;
2807 LDPARMS rnd;
2808 LDPARMS *ldp = &rnd;
2809 char *outstr;
2810 char outbuf_sml[NDEC_SML + MAX_EXP_DIGITS + 10];
2811 char *outbuf = outbuf_sml;
2812 union uconv du;
2813 du.d = d;
2814
2815 orig_ndigits = ndigits;
2816 rnd.rlast = -1;
2817 rnd.rndprc = NBITS;
2818
2819 #if LDBL_MANT_DIG == 24
2820 e24toe (&du.pe, e, ldp);
2821 #elif LDBL_MANT_DIG == 53
2822 e53toe (&du.pe, e, ldp);
2823 #elif LDBL_MANT_DIG == 64
2824 e64toe (&du.pe, e, ldp);
2825 #else
2826 e113toe (&du.pe, e, ldp);
2827 #endif
2828
2829 if (eisneg (e))
2830 *sign = 1;
2831 else
2832 *sign = 0;
2833 /* Mode 3 is "f" format. */
2834 if (mode != 3)
2835 ndigits -= 1;
2836 /* Mode 0 is for %.999 format, which is supposed to give a
2837 minimum length string that will convert back to the same binary value.
2838 For now, just ask for 20 digits which is enough but sometimes too many. */
2839 if (mode == 0)
2840 ndigits = 20;
2841
2842 /* This sanity limit must agree with the corresponding one in etoasc, to
2843 keep straight the returned value of outexpon. Note that we use a dynamic
2844 limit now, either ndec (<= NDEC) or NDEC_SML, depending on ndigits. */
2845 __int32_t ndec;
2846 if (mode == 3) /* %f */
2847 {
2848 __int32_t expon = (e[NE - 1] & 0x7fff) - (EXONE - 1); /* exponent part */
2849 /* log2(10) approximately 485/146 */
2850 ndec = expon * 146 / 485 + ndigits;
2851 }
2852 else /* %g/%e */
2853 ndec = ndigits;
2854 if (ndec < 0)
2855 ndec = 0;
2856 if (ndec > NDEC)
2857 ndec = NDEC;
2858
2859 /* Allocate buffer if more than NDEC_SML digits are requested. */
2860 if (ndec > NDEC_SML)
2861 {
2862 outbuf = (char *) malloc (ndec + MAX_EXP_DIGITS + 10);
2863 if (!outbuf)
2864 {
2865 ndec = NDEC_SML;
2866 outbuf = outbuf_sml;
2867 }
2868 }
2869
2870 etoasc (e, outbuf, (int) ndec, ndigits, mode, ldp);
2871 s = outbuf;
2872 if (eisinf (e) || eisnan (e))
2873 {
2874 *decpt = 9999;
2875 goto stripspaces;
2876 }
2877 *decpt = ldp->outexpon + 1;
2878
2879 /* Transform the string returned by etoasc into what the caller wants. */
2880
2881 /* Look for decimal point and delete it from the string. */
2882 s = outbuf;
2883 while (*s != '\0')
2884 {
2885 if (*s == '.')
2886 goto yesdecpt;
2887 ++s;
2888 }
2889 goto nodecpt;
2890
2891 yesdecpt:
2892
2893 /* Delete the decimal point. */
2894 while (*s != '\0')
2895 {
2896 *s = *(s + 1);
2897 ++s;
2898 }
2899
2900 nodecpt:
2901
2902 /* Back up over the exponent field. */
2903 while (*s != 'E' && s > outbuf)
2904 --s;
2905 *s = '\0';
2906
2907 stripspaces:
2908
2909 /* Strip leading spaces and sign. */
2910 p = outbuf;
2911 while (*p == ' ' || *p == '-')
2912 ++p;
2913
2914 /* Find new end of string. */
2915 s = outbuf;
2916 while ((*s++ = *p++) != '\0')
2917 ;
2918 --s;
2919
2920 /* Strip trailing zeros. */
2921 if (mode == 2)
2922 k = 1;
2923 else if (ndigits > ldp->outexpon)
2924 k = ndigits;
2925 else
2926 k = ldp->outexpon;
2927
2928 while (*(s - 1) == '0' && ((s - outbuf) > k))
2929 *(--s) = '\0';
2930
2931 /* In f format, flush small off-scale values to zero.
2932 Rounding has been taken care of by etoasc. */
2933 if (mode == 3 && ((ndigits + ldp->outexpon) < 0))
2934 {
2935 s = outbuf;
2936 *s = '\0';
2937 *decpt = 0;
2938 }
2939
2940 /* we want to have enough space to hold the formatted result */
2941
2942 if (mode == 3) /* f format, account for sign + dec digits + decpt + frac */
2943 i = *decpt + orig_ndigits + 3;
2944 else /* account for sign + max precision digs + E + exp sign + exponent */
2945 i = orig_ndigits + MAX_EXP_DIGITS + 4;
2946
2947 outstr = __alloc_dtoa_result(i);
2948 if (!outstr)
2949 return NULL;
2950
2951 /* Copy from internal temporary buffer to permanent buffer. */
2952 strcpy (outstr, outbuf);
2953
2954 if (rve)
2955 *rve = outstr + (s - outbuf);
2956
2957 if (outbuf != outbuf_sml)
2958 free (outbuf);
2959
2960 return outstr;
2961 }
2962
2963 /* Routine used to tell if long double is NaN or Infinity or regular number.
2964 Returns: 0 = regular number
2965 1 = Nan
2966 2 = Infinity
2967 */
2968 int
_ldcheck(long double * d)2969 _ldcheck (long double *d)
2970 {
2971 unsigned short e[NI] = {0};
2972 LDPARMS rnd;
2973 LDPARMS *ldp = &rnd;
2974
2975 union uconv du;
2976
2977 rnd.rlast = -1;
2978 rnd.rndprc = NBITS;
2979 du.d = *d;
2980 #if LDBL_MANT_DIG == 24
2981 e24toe (&du.pe, e, ldp);
2982 #elif LDBL_MANT_DIG == 53
2983 e53toe (&du.pe, e, ldp);
2984 #elif LDBL_MANT_DIG == 64
2985 e64toe (&du.pe, e, ldp);
2986 #else
2987 e113toe (&du.pe, e, ldp);
2988 #endif
2989
2990 if ((e[NE - 1] & 0x7fff) == 0x7fff)
2991 {
2992 #ifdef NANS
2993 if (eisnan (e))
2994 return (1);
2995 #endif
2996 return (2);
2997 }
2998 else
2999 return (0);
3000 } /* _ldcheck */
3001
3002 static void
etoasc(short unsigned int * x,char * string,int ndec,int ndigits,int outformat,LDPARMS * ldp)3003 etoasc (short unsigned int *x, char *string, int ndec, int ndigits,
3004 int outformat, LDPARMS * ldp)
3005 {
3006 long digit;
3007 unsigned short y[NI] = {0}, t[NI] = {0}, u[NI] = {0}, w[NI] = {0};
3008 const unsigned short *p, *r, *ten;
3009 unsigned short sign;
3010 int i, j, k, expon, rndsav, ndigs;
3011 char *s, *ss;
3012 unsigned short m;
3013 unsigned short *equot = ldp->equot;
3014
3015 ndigs = ndigits;
3016 rndsav = ldp->rndprc;
3017 #ifdef NANS
3018 if (eisnan (x))
3019 {
3020 sprintf (string, " NaN ");
3021 expon = 9999;
3022 goto bxit;
3023 }
3024 #endif
3025 ldp->rndprc = NBITS; /* set to full precision */
3026 emov (x, y); /* retain external format */
3027 if (y[NE - 1] & 0x8000)
3028 {
3029 sign = 0xffff;
3030 y[NE - 1] &= 0x7fff;
3031 }
3032 else
3033 {
3034 sign = 0;
3035 }
3036 expon = 0;
3037 ten = &etens[NTEN][0];
3038 emov (eone, t);
3039 /* Test for zero exponent */
3040 if (y[NE - 1] == 0)
3041 {
3042 for (k = 0; k < NE - 1; k++)
3043 {
3044 if (y[k] != 0)
3045 goto tnzro; /* denormalized number */
3046 }
3047 goto isone; /* legal all zeros */
3048 }
3049 tnzro:
3050
3051 /* Test for infinity.
3052 */
3053 if (y[NE - 1] == 0x7fff)
3054 {
3055 if (sign)
3056 sprintf (string, " -Infinity ");
3057 else
3058 sprintf (string, " Infinity ");
3059 expon = 9999;
3060 goto bxit;
3061 }
3062
3063 /* Test for exponent nonzero but significand denormalized.
3064 * This is an error condition.
3065 */
3066 if ((y[NE - 1] != 0) && ((y[NE - 2] & 0x8000) == 0))
3067 {
3068 mtherr ("etoasc", DOMAIN);
3069 sprintf (string, "NaN");
3070 expon = 9999;
3071 goto bxit;
3072 }
3073
3074 /* Compare to 1.0 */
3075 i = ecmp (eone, y);
3076 if (i == 0)
3077 goto isone;
3078
3079 if (i < 0)
3080 { /* Number is greater than 1 */
3081 /* Convert significand to an integer and strip trailing decimal zeros. */
3082 emov (y, u);
3083 u[NE - 1] = EXONE + NBITS - 1;
3084
3085 p = &etens[NTEN - 4][0];
3086 m = 16;
3087 do
3088 {
3089 ediv (p, u, t, ldp);
3090 efloor (t, w, ldp);
3091 for (j = 0; j < NE - 1; j++)
3092 {
3093 if (t[j] != w[j])
3094 goto noint;
3095 }
3096 emov (t, u);
3097 expon += (int) m;
3098 noint:
3099 p += NE;
3100 m >>= 1;
3101 }
3102 while (m != 0);
3103
3104 /* Rescale from integer significand */
3105 u[NE - 1] += y[NE - 1] - (unsigned int) (EXONE + NBITS - 1);
3106 emov (u, y);
3107 /* Find power of 10 */
3108 emov (eone, t);
3109 m = MAXP;
3110 p = &etens[0][0];
3111 while (ecmp (ten, u) <= 0)
3112 {
3113 if (ecmp (p, u) <= 0)
3114 {
3115 ediv (p, u, u, ldp);
3116 emul (p, t, t, ldp);
3117 expon += (int) m;
3118 }
3119 m >>= 1;
3120 if (m == 0)
3121 break;
3122 p += NE;
3123 }
3124 }
3125 else
3126 { /* Number is less than 1.0 */
3127 /* Pad significand with trailing decimal zeros. */
3128 if (y[NE - 1] == 0)
3129 {
3130 while ((y[NE - 2] & 0x8000) == 0)
3131 {
3132 emul (ten, y, y, ldp);
3133 expon -= 1;
3134 }
3135 }
3136 else
3137 {
3138 emovi (y, w);
3139 for (i = 0; i < ndec + 1; i++)
3140 {
3141 if ((w[NI - 1] & 0x7) != 0)
3142 break;
3143 /* multiply by 10 */
3144 emovz (w, u);
3145 eshdn1 (u);
3146 eshdn1 (u);
3147 eaddm (w, u);
3148 u[1] += 3;
3149 while (u[2] != 0)
3150 {
3151 eshdn1 (u);
3152 u[1] += 1;
3153 }
3154 if (u[NI - 1] != 0)
3155 break;
3156 if (eone[NE - 1] <= u[1])
3157 break;
3158 emovz (u, w);
3159 expon -= 1;
3160 }
3161 emovo (w, y, ldp);
3162 }
3163 k = -MAXP;
3164 p = &emtens[0][0];
3165 r = &etens[0][0];
3166 emov (y, w);
3167 emov (eone, t);
3168 while (ecmp (eone, w) > 0)
3169 {
3170 if (ecmp (p, w) >= 0)
3171 {
3172 emul (r, w, w, ldp);
3173 emul (r, t, t, ldp);
3174 expon += k;
3175 }
3176 k /= 2;
3177 if (k == 0)
3178 break;
3179 p += NE;
3180 r += NE;
3181 }
3182 ediv (t, eone, t, ldp);
3183 }
3184 isone:
3185 /* Find the first (leading) digit. */
3186 emovi (t, w);
3187 emovz (w, t);
3188 emovi (y, w);
3189 emovz (w, y);
3190 eiremain (t, y, ldp);
3191 digit = equot[NI - 1];
3192 while ((digit == 0) && (ecmp (y, ezero) != 0))
3193 {
3194 eshup1 (y);
3195 emovz (y, u);
3196 eshup1 (u);
3197 eshup1 (u);
3198 eaddm (u, y);
3199 eiremain (t, y, ldp);
3200 digit = equot[NI - 1];
3201 expon -= 1;
3202 }
3203 s = string;
3204 if (sign)
3205 *s++ = '-';
3206 else
3207 *s++ = ' ';
3208 /* Examine number of digits requested by caller. */
3209 if (outformat == 3)
3210 ndigs += expon;
3211 /*
3212 else if( ndigs < 0 )
3213 ndigs = 0;
3214 */
3215 if (ndigs > ndec)
3216 ndigs = ndec;
3217 if (digit == 10)
3218 {
3219 *s++ = '1';
3220 *s++ = '.';
3221 if (ndigs > 0)
3222 {
3223 *s++ = '0';
3224 ndigs -= 1;
3225 }
3226 expon += 1;
3227 if (ndigs < 0)
3228 {
3229 ss = s;
3230 goto doexp;
3231 }
3232 }
3233 else
3234 {
3235 *s++ = (char) digit + '0';
3236 *s++ = '.';
3237 }
3238 /* Generate digits after the decimal point. */
3239 for (k = 0; k <= ndigs; k++)
3240 {
3241 /* multiply current number by 10, without normalizing */
3242 eshup1 (y);
3243 emovz (y, u);
3244 eshup1 (u);
3245 eshup1 (u);
3246 eaddm (u, y);
3247 eiremain (t, y, ldp);
3248 *s++ = (char) equot[NI - 1] + '0';
3249 }
3250 digit = equot[NI - 1];
3251 --s;
3252 ss = s;
3253 /* round off the ASCII string */
3254 if (digit > 4)
3255 {
3256 /* Test for critical rounding case in ASCII output. */
3257 if (digit == 5)
3258 {
3259 emovo (y, t, ldp);
3260 if (ecmp (t, ezero) != 0)
3261 goto roun; /* round to nearest */
3262 if (ndigs < 0 || (*(s - 1 - (*(s - 1) == '.')) & 1) == 0)
3263 goto doexp; /* round to even */
3264 }
3265 /* Round up and propagate carry-outs */
3266 roun:
3267 --s;
3268 k = *s & 0x7f;
3269 /* Carry out to most significant digit? */
3270 if (ndigs < 0)
3271 {
3272 /* This will print like "1E-6". */
3273 *s = '1';
3274 expon += 1;
3275 goto doexp;
3276 }
3277 else if (k == '.')
3278 {
3279 --s;
3280 k = *s;
3281 k += 1;
3282 *s = (char) k;
3283 /* Most significant digit carries to 10? */
3284 if (k > '9')
3285 {
3286 expon += 1;
3287 *s = '1';
3288 }
3289 goto doexp;
3290 }
3291 /* Round up and carry out from less significant digits */
3292 k += 1;
3293 *s = (char) k;
3294 if (k > '9')
3295 {
3296 *s = '0';
3297 goto roun;
3298 }
3299 }
3300 doexp:
3301 #ifdef __GO32__
3302 if (expon >= 0)
3303 sprintf (ss, "e+%02d", expon);
3304 else
3305 sprintf (ss, "e-%02d", -expon);
3306 #else
3307 sprintf (ss, "E%d", expon);
3308 #endif
3309 bxit:
3310 ldp->rndprc = rndsav;
3311 ldp->outexpon = expon;
3312 }
3313
3314
3315 #if 0 /* Broken, unusable implementation of strtold */
3316
3317 /*
3318 ; ASCTOQ
3319 ; ASCTOQ.MAC LATEST REV: 11 JAN 84
3320 ; SLM, 3 JAN 78
3321 ;
3322 ; Convert ASCII string to quadruple precision floating point
3323 ;
3324 ; Numeric input is free field decimal number
3325 ; with max of 15 digits with or without
3326 ; decimal point entered as ASCII from teletype.
3327 ; Entering E after the number followed by a second
3328 ; number causes the second number to be interpreted
3329 ; as a power of 10 to be multiplied by the first number
3330 ; (i.e., "scientific" notation).
3331 ;
3332 ; Usage:
3333 ; asctoq( string, q );
3334 */
3335
3336 long double
3337 strtold (char *s, char **se)
3338 {
3339 union uconv x;
3340 LDPARMS rnd;
3341 LDPARMS *ldp = &rnd;
3342 int lenldstr;
3343
3344 rnd.rlast = -1;
3345 rnd.rndprc = NBITS;
3346
3347 lenldstr = asctoeg (s, &x.pe, LDBL_MANT_DIG, ldp);
3348 if (se)
3349 *se = s + lenldstr;
3350 return x.d;
3351 }
3352
3353 #define REASONABLE_LEN 200
3354
3355 static int
3356 asctoeg (char *ss, short unsigned int *y, int oprec, LDPARMS * ldp)
3357 {
3358 unsigned short yy[NI] = {0}, xt[NI] = {0}, tt[NI] = {0};
3359 int esign, decflg, sgnflg, nexp, exp, prec, lost;
3360 int k, trail, c, rndsav;
3361 long lexp;
3362 unsigned short nsign;
3363 const unsigned short *p;
3364 char *sp, *s, *lstr;
3365 int lenldstr;
3366 int mflag = 0;
3367 char tmpstr[REASONABLE_LEN];
3368
3369 /* Copy the input string. */
3370 c = strlen (ss) + 2;
3371 if (c <= REASONABLE_LEN)
3372 lstr = tmpstr;
3373 else
3374 {
3375 lstr = (char *) calloc (c, 1);
3376 mflag = 1;
3377 }
3378 s = ss;
3379 lenldstr = 0;
3380 while (*s == ' ') /* skip leading spaces */
3381 {
3382 ++s;
3383 ++lenldstr;
3384 }
3385 sp = lstr;
3386 for (k = 0; k < c; k++)
3387 {
3388 if ((*sp++ = *s++) == '\0')
3389 break;
3390 }
3391 *sp = '\0';
3392 s = lstr;
3393
3394 rndsav = ldp->rndprc;
3395 ldp->rndprc = NBITS; /* Set to full precision */
3396 lost = 0;
3397 nsign = 0;
3398 decflg = 0;
3399 sgnflg = 0;
3400 nexp = 0;
3401 exp = 0;
3402 prec = 0;
3403 ecleaz (yy);
3404 trail = 0;
3405
3406 nxtcom:
3407 k = *s - '0';
3408 if ((k >= 0) && (k <= 9))
3409 {
3410 /* Ignore leading zeros */
3411 if ((prec == 0) && (decflg == 0) && (k == 0))
3412 goto donchr;
3413 /* Identify and strip trailing zeros after the decimal point. */
3414 if ((trail == 0) && (decflg != 0))
3415 {
3416 sp = s;
3417 while ((*sp >= '0') && (*sp <= '9'))
3418 ++sp;
3419 /* Check for syntax error */
3420 c = *sp & 0x7f;
3421 if ((c != 'e') && (c != 'E') && (c != '\0')
3422 && (c != '\n') && (c != '\r') && (c != ' ') && (c != ','))
3423 goto error;
3424 --sp;
3425 while (*sp == '0')
3426 *sp-- = 'z';
3427 trail = 1;
3428 if (*s == 'z')
3429 goto donchr;
3430 }
3431 /* If enough digits were given to more than fill up the yy register,
3432 * continuing until overflow into the high guard word yy[2]
3433 * guarantees that there will be a roundoff bit at the top
3434 * of the low guard word after normalization.
3435 */
3436 if (yy[2] == 0)
3437 {
3438 if (decflg)
3439 nexp += 1; /* count digits after decimal point */
3440 eshup1 (yy); /* multiply current number by 10 */
3441 emovz (yy, xt);
3442 eshup1 (xt);
3443 eshup1 (xt);
3444 eaddm (xt, yy);
3445 ecleaz (xt);
3446 xt[NI - 2] = (unsigned short) k;
3447 eaddm (xt, yy);
3448 }
3449 else
3450 {
3451 /* Mark any lost non-zero digit. */
3452 lost |= k;
3453 /* Count lost digits before the decimal point. */
3454 if (decflg == 0)
3455 nexp -= 1;
3456 }
3457 prec += 1;
3458 goto donchr;
3459 }
3460
3461 switch (*s)
3462 {
3463 case 'z':
3464 break;
3465 case 'E':
3466 case 'e':
3467 goto expnt;
3468 case '.': /* decimal point */
3469 if (decflg)
3470 goto error;
3471 ++decflg;
3472 break;
3473 case '-':
3474 nsign = 0xffff;
3475 if (sgnflg)
3476 goto error;
3477 ++sgnflg;
3478 break;
3479 case '+':
3480 if (sgnflg)
3481 goto error;
3482 ++sgnflg;
3483 break;
3484 case ',':
3485 case ' ':
3486 case '\0':
3487 case '\n':
3488 case '\r':
3489 goto daldone;
3490 case 'i':
3491 case 'I':
3492 goto infinite;
3493 default:
3494 error:
3495 #ifdef NANS
3496 enan (yy, NI * 16);
3497 #else
3498 mtherr ("asctoe", DOMAIN);
3499 ecleaz (yy);
3500 #endif
3501 goto aexit;
3502 }
3503 donchr:
3504 ++s;
3505 goto nxtcom;
3506
3507 /* Exponent interpretation */
3508 expnt:
3509
3510 esign = 1;
3511 exp = 0;
3512 ++s;
3513 /* check for + or - */
3514 if (*s == '-')
3515 {
3516 esign = -1;
3517 ++s;
3518 }
3519 if (*s == '+')
3520 ++s;
3521 while ((*s >= '0') && (*s <= '9'))
3522 {
3523 exp *= 10;
3524 exp += *s++ - '0';
3525 if (exp > 4977)
3526 {
3527 if (esign < 0)
3528 goto zero;
3529 else
3530 goto infinite;
3531 }
3532 }
3533 if (esign < 0)
3534 exp = -exp;
3535 if (exp > 4932)
3536 {
3537 infinite:
3538 ecleaz (yy);
3539 yy[E] = 0x7fff; /* infinity */
3540 goto aexit;
3541 }
3542 if (exp < -4977)
3543 {
3544 zero:
3545 ecleaz (yy);
3546 goto aexit;
3547 }
3548
3549 daldone:
3550 nexp = exp - nexp;
3551 /* Pad trailing zeros to minimize power of 10, per IEEE spec. */
3552 while ((nexp > 0) && (yy[2] == 0))
3553 {
3554 emovz (yy, xt);
3555 eshup1 (xt);
3556 eshup1 (xt);
3557 eaddm (yy, xt);
3558 eshup1 (xt);
3559 if (xt[2] != 0)
3560 break;
3561 nexp -= 1;
3562 emovz (xt, yy);
3563 }
3564 if ((k = enormlz (yy)) > NBITS)
3565 {
3566 ecleaz (yy);
3567 goto aexit;
3568 }
3569 lexp = (EXONE - 1 + NBITS) - k;
3570 emdnorm (yy, lost, 0, lexp, 64, ldp);
3571 /* convert to external format */
3572
3573
3574 /* Multiply by 10**nexp. If precision is 64 bits,
3575 * the maximum relative error incurred in forming 10**n
3576 * for 0 <= n <= 324 is 8.2e-20, at 10**180.
3577 * For 0 <= n <= 999, the peak relative error is 1.4e-19 at 10**947.
3578 * For 0 >= n >= -999, it is -1.55e-19 at 10**-435.
3579 */
3580 lexp = yy[E];
3581 if (nexp == 0)
3582 {
3583 k = 0;
3584 goto expdon;
3585 }
3586 esign = 1;
3587 if (nexp < 0)
3588 {
3589 nexp = -nexp;
3590 esign = -1;
3591 if (nexp > 4096)
3592 { /* Punt. Can't handle this without 2 divides. */
3593 emovi (etens[0], tt);
3594 lexp -= tt[E];
3595 k = edivm (tt, yy, ldp);
3596 lexp += EXONE;
3597 nexp -= 4096;
3598 }
3599 }
3600 p = &etens[NTEN][0];
3601 emov (eone, xt);
3602 exp = 1;
3603 do
3604 {
3605 if (exp & nexp)
3606 emul (p, xt, xt, ldp);
3607 p -= NE;
3608 exp = exp + exp;
3609 }
3610 while (exp <= MAXP);
3611
3612 emovi (xt, tt);
3613 if (esign < 0)
3614 {
3615 lexp -= tt[E];
3616 k = edivm (tt, yy, ldp);
3617 lexp += EXONE;
3618 }
3619 else
3620 {
3621 lexp += tt[E];
3622 k = emulm (tt, yy, ldp);
3623 lexp -= EXONE - 1;
3624 }
3625
3626 expdon:
3627
3628 /* Round and convert directly to the destination type */
3629 if (oprec == 53)
3630 lexp -= EXONE - 0x3ff;
3631 else if (oprec == 24)
3632 lexp -= EXONE - 0177;
3633 #ifdef DEC
3634 else if (oprec == 56)
3635 lexp -= EXONE - 0201;
3636 #endif
3637 ldp->rndprc = oprec;
3638 emdnorm (yy, k, 0, lexp, 64, ldp);
3639
3640 aexit:
3641
3642 ldp->rndprc = rndsav;
3643 yy[0] = nsign;
3644 switch (oprec)
3645 {
3646 #ifdef DEC
3647 case 56:
3648 todec (yy, y); /* see etodec.c */
3649 break;
3650 #endif
3651 #if LDBL_MANT_DIG == 53
3652 case 53:
3653 toe53 (yy, y);
3654 break;
3655 #elif LDBL_MANT_DIG == 24
3656 case 24:
3657 toe24 (yy, y);
3658 break;
3659 #elif LDBL_MANT_DIG == 64
3660 case 64:
3661 toe64 (yy, y);
3662 break;
3663 #elif LDBL_MANT_DIG == 113
3664 case 113:
3665 toe113 (yy, y);
3666 break;
3667 #else
3668 case NBITS:
3669 emovo (yy, y, ldp);
3670 break;
3671 #endif
3672 }
3673 lenldstr += s - lstr;
3674 if (mflag)
3675 free (lstr);
3676 return lenldstr;
3677 }
3678
3679 #endif
3680
3681 /* y = largest integer not greater than x
3682 * (truncated toward minus infinity)
3683 *
3684 * unsigned short x[NE], y[NE]
3685 * LDPARMS *ldp
3686 *
3687 * efloor( x, y, ldp );
3688 */
3689 static const unsigned short bmask[] = {
3690 0xffff,
3691 0xfffe,
3692 0xfffc,
3693 0xfff8,
3694 0xfff0,
3695 0xffe0,
3696 0xffc0,
3697 0xff80,
3698 0xff00,
3699 0xfe00,
3700 0xfc00,
3701 0xf800,
3702 0xf000,
3703 0xe000,
3704 0xc000,
3705 0x8000,
3706 0x0000,
3707 };
3708
3709 static void
efloor(short unsigned int * x,short unsigned int * y,LDPARMS * ldp)3710 efloor (short unsigned int *x, short unsigned int *y, LDPARMS * ldp)
3711 {
3712 register unsigned short *p;
3713 int e, expon, i;
3714 unsigned short f[NE];
3715
3716 emov (x, f); /* leave in external format */
3717 expon = (int) f[NE - 1];
3718 e = (expon & 0x7fff) - (EXONE - 1);
3719 if (e <= 0)
3720 {
3721 eclear (y);
3722 goto isitneg;
3723 }
3724 /* number of bits to clear out */
3725 e = NBITS - e;
3726 emov (f, y);
3727 if (e <= 0)
3728 return;
3729
3730 p = &y[0];
3731 while (e >= 16)
3732 {
3733 *p++ = 0;
3734 e -= 16;
3735 }
3736 /* clear the remaining bits */
3737 *p &= bmask[e];
3738 /* truncate negatives toward minus infinity */
3739 isitneg:
3740
3741 if ((unsigned short) expon & (unsigned short) 0x8000)
3742 {
3743 for (i = 0; i < NE - 1; i++)
3744 {
3745 if (f[i] != y[i])
3746 {
3747 esub (eone, y, y, ldp);
3748 break;
3749 }
3750 }
3751 }
3752 }
3753
3754
3755
3756 static void
eiremain(short unsigned int * den,short unsigned int * num,LDPARMS * ldp)3757 eiremain (short unsigned int *den, short unsigned int *num, LDPARMS * ldp)
3758 {
3759 long ld, ln;
3760 unsigned short j;
3761 unsigned short *equot = ldp->equot;
3762
3763 ld = den[E];
3764 ld -= enormlz (den);
3765 ln = num[E];
3766 ln -= enormlz (num);
3767 ecleaz (equot);
3768 while (ln >= ld)
3769 {
3770 if (ecmpm (den, num) <= 0)
3771 {
3772 esubm (den, num);
3773 j = 1;
3774 }
3775 else
3776 {
3777 j = 0;
3778 }
3779 eshup1 (equot);
3780 equot[NI - 1] |= j;
3781 eshup1 (num);
3782 ln -= 1;
3783 }
3784 emdnorm (num, 0, 0, ln, 0, ldp);
3785 }
3786
3787 /* NaN bit patterns
3788 */
3789 #ifdef MIEEE
3790 #if !defined(__mips)
3791 static const unsigned short nan113[8] = {
3792 0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
3793 };
3794
3795 static const unsigned short nan64[6] = {
3796 0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
3797 };
3798 static const unsigned short nan53[4] = { 0x7fff, 0xffff, 0xffff, 0xffff };
3799 static const unsigned short nan24[2] = { 0x7fff, 0xffff };
3800 #elif defined(__mips_nan2008) /* __mips */
3801 static const unsigned short nan113[8] = { 0x7fff, 0x8000, 0, 0, 0, 0, 0, 0 };
3802 static const unsigned short nan64[6] = { 0x7fff, 0xc000, 0, 0, 0, 0 };
3803 static const unsigned short nan53[4] = { 0x7ff8, 0, 0, 0 };
3804 static const unsigned short nan24[2] = { 0x7fc0, 0 };
3805 #else /* __mips && !__mips_nan2008 */
3806 static const unsigned short nan113[8] = {
3807 0x7fff, 0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
3808 };
3809
3810 static const unsigned short nan64[6] = {
3811 0x7fff, 0xbfff, 0xffff, 0xffff, 0xffff, 0xffff
3812 };
3813 static const unsigned short nan53[4] = { 0x7ff7, 0xffff, 0xffff, 0xffff };
3814 static const unsigned short nan24[2] = { 0x7fbf, 0xffff };
3815 #endif /* __mips && !__mips_nan2008 */
3816 #else /* !MIEEE */
3817 #if !defined(__mips) || defined(__mips_nan2008)
3818 static const unsigned short nan113[8] = { 0, 0, 0, 0, 0, 0, 0x8000, 0x7fff };
3819 static const unsigned short nan64[6] = { 0, 0, 0, 0, 0xc000, 0x7fff };
3820 static const unsigned short nan53[4] = { 0, 0, 0, 0x7ff8 };
3821 static const unsigned short nan24[2] = { 0, 0x7fc0 };
3822 #else /* __mips && !__mips_nan2008 */
3823 static const unsigned short nan113[8] = {
3824 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x7fff, 0x7fff
3825 };
3826
3827 static const unsigned short nan64[6] = {
3828 0xffff, 0xffff, 0xffff, 0xffff, 0xbfff, 0x7fff
3829 };
3830 static const unsigned short nan53[4] = { 0xffff, 0xffff, 0xffff, 0x7ff7 };
3831 static const unsigned short nan24[2] = { 0xffff, 0x7fbf };
3832 #endif /* __mips && !__mips_nan2008 */
3833 #endif /* !MIEEE */
3834
3835
3836 static void
enan(short unsigned int * nan,int size)3837 enan (short unsigned int *nan, int size)
3838 {
3839 int i, n;
3840 const unsigned short *p;
3841
3842 switch (size)
3843 {
3844 #ifndef DEC
3845 case 113:
3846 n = 8;
3847 p = nan113;
3848 break;
3849
3850 case 64:
3851 n = 6;
3852 p = nan64;
3853 break;
3854
3855 case 53:
3856 n = 4;
3857 p = nan53;
3858 break;
3859
3860 case 24:
3861 n = 2;
3862 p = nan24;
3863 break;
3864
3865 case NBITS:
3866 #if !defined(__mips) || defined(__mips_nan2008)
3867 for (i = 0; i < NE - 2; i++)
3868 *nan++ = 0;
3869 *nan++ = 0xc000;
3870 #else /* __mips && !__mips_nan2008 */
3871 for (i = 0; i < NE - 2; i++)
3872 *nan++ = 0xffff;
3873 *nan++ = 0xbfff;
3874 #endif /* __mips && !__mips_nan2008 */
3875 *nan++ = 0x7fff;
3876 return;
3877
3878 case NI * 16:
3879 *nan++ = 0;
3880 *nan++ = 0x7fff;
3881 *nan++ = 0;
3882 #if !defined(__mips) || defined(__mips_nan2008)
3883 *nan++ = 0xc000;
3884 for (i = 4; i < NI - 1; i++)
3885 *nan++ = 0;
3886 #else /* __mips && !__mips_nan2008 */
3887 *nan++ = 0xbfff;
3888 for (i = 4; i < NI - 1; i++)
3889 *nan++ = 0xffff;
3890 #endif /* __mips && !__mips_nan2008 */
3891 *nan++ = 0;
3892 return;
3893 #endif
3894 default:
3895 mtherr ("enan", DOMAIN);
3896 return;
3897 }
3898 for (i = 0; i < n; i++)
3899 *nan++ = *p++;
3900 }
3901
3902 #endif /* !_USE_GDTOA */
3903