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