2 /* Extended precision arithmetic functions for long double I/O.
3 * This program has been placed in the public domain.
15 /* These are the externally visible entries. */
16 /* linux name: long double _IO_strtold (char *, char **); */
17 void _simdstrtold (char *, char **, LONG_DOUBLE_UNION
*);
18 char * _simdldtoa_r (struct _reent
*, LONG_DOUBLE_UNION
*, int, int, int *, int *, char **);
20 /* Number of 16 bit words in external x type format */
23 /* Number of 16 bit words in internal format */
26 /* Array offset to exponent */
29 /* Array offset to high guard word */
32 /* Number of bits of precision */
33 #define NBITS ((NI-4)*16)
35 /* Maximum number of decimal digits in ASCII conversion
38 #define NDEC (NBITS*8/27)
40 /* The exponent of 1.0 */
41 #define EXONE (0x3fff)
43 /* Maximum exponent digits - base 10 */
44 #define MAX_EXP_DIGITS 5
46 /* Control structure for long doublue conversion including rounding precision values.
47 * rndprc can be set to 80 (if NE=6), 64, 56, 53, or 24 bits.
59 unsigned short rbit
[NI
];
60 unsigned short equot
[NI
];
63 static void esub(short unsigned int *a
, short unsigned int *b
, short unsigned int *c
, LDPARMS
*ldp
);
64 static void emul(short unsigned int *a
, short unsigned int *b
, short unsigned int *c
, LDPARMS
*ldp
);
65 static void ediv(short unsigned int *a
, short unsigned int *b
, short unsigned int *c
, LDPARMS
*ldp
);
66 static int ecmp(short unsigned int *a
, short unsigned int *b
);
67 static int enormlz(short unsigned int *x
);
68 static int eshift(short unsigned int *x
, int sc
);
69 static void eshup1(register short unsigned int *x
);
70 static void eshup8(register short unsigned int *x
);
71 static void eshup6(register short unsigned int *x
);
72 static void eshdn1(register short unsigned int *x
);
73 static void eshdn8(register short unsigned int *x
);
74 static void eshdn6(register short unsigned int *x
);
75 static void eneg(short unsigned int *x
);
76 static void emov(register short unsigned int *a
, register short unsigned int *b
);
77 static void eclear(register short unsigned int *x
);
78 static void einfin(register short unsigned int *x
, register LDPARMS
*ldp
);
79 static void efloor(short unsigned int *x
, short unsigned int *y
, LDPARMS
*ldp
);
80 static void etoasc(short unsigned int *x
, char *string
, int ndigs
, int outformat
, LDPARMS
*ldp
);
82 #if SIMD_LDBL_MANT_DIG == 24
83 static void e24toe(short unsigned int *pe
, short unsigned int *y
, LDPARMS
*ldp
);
84 #elif SIMD_LDBL_MANT_DIG == 53
85 static void e53toe(short unsigned int *pe
, short unsigned int *y
, LDPARMS
*ldp
);
86 #elif SIMD_LDBL_MANT_DIG == 64
87 static void e64toe(short unsigned int *pe
, short unsigned int *y
, LDPARMS
*ldp
);
89 static void e113toe(short unsigned int *pe
, short unsigned int *y
, LDPARMS
*ldp
);
93 /* e type constants used by high precision check routines */
97 static unsigned short ezero
[NE
] =
98 {0x0000, 0x0000, 0x0000, 0x0000,
99 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,};
102 static unsigned short eone
[NE
] =
103 {0x0000, 0x0000, 0x0000, 0x0000,
104 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x3fff,};
109 static unsigned short ezero
[NE
] = {
110 0, 0000000,0000000,0000000,0000000,0000000,};
112 static unsigned short eone
[NE
] = {
113 0, 0000000,0000000,0000000,0100000,0x3fff,};
117 /* Debugging routine for displaying errors */
119 /* Notice: the order of appearance of the following
120 * messages is bound to the error codes defined
123 static char *ermsg
[7] = {
124 "unknown", /* error code 0 */
125 "domain", /* error code 1 */
126 "singularity", /* et seq. */
129 "total loss of precision",
130 "partial loss of precision"
132 #define mtherr(name, code) printf( "\n%s %s error\n", name, ermsg[code] );
134 #define mtherr(name, code)
139 * Extended precision IEEE binary floating point arithmetic routines
141 * Numbers are stored in C language as arrays of 16-bit unsigned
142 * short integers. The arguments of the routines are pointers to
146 * External e type data structure, simulates Intel 8087 chip
147 * temporary real format but possibly with a larger significand:
149 * NE-1 significand words (least significant word first,
150 * most significant bit is normally set)
151 * exponent (value = EXONE for 1.0,
152 * top bit is the sign)
155 * Internal data structure of a number (a "word" is 16 bits):
157 * ei[0] sign word (0 for positive, 0xffff for negative)
158 * ei[1] biased exponent (value = EXONE for the number 1.0)
159 * ei[2] high guard word (always zero after normalization)
161 * to ei[NI-2] significand (NI-4 significand words,
162 * most significant word first,
163 * most significant bit is set)
164 * ei[NI-1] low guard word (0x8000 bit is rounding place)
168 * Routines for external format numbers
170 * asctoe( string, e ) ASCII string to extended double e type
171 * asctoe64( string, &d ) ASCII string to long double
172 * asctoe53( string, &d ) ASCII string to double
173 * asctoe24( string, &f ) ASCII string to single
174 * asctoeg( string, e, prec, ldp ) ASCII string to specified precision
175 * e24toe( &f, e, ldp ) IEEE single precision to e type
176 * e53toe( &d, e, ldp ) IEEE double precision to e type
177 * e64toe( &d, e, ldp ) IEEE long double precision to e type
178 * e113toe( &d, e, ldp ) IEEE long double precision to e type
179 * eabs(e) absolute value
180 * eadd( a, b, c ) c = b + a
182 * ecmp (a, b) Returns 1 if a > b, 0 if a == b,
183 * -1 if a < b, -2 if either a or b is a NaN.
184 * ediv( a, b, c, ldp ) c = b / a
185 * efloor( a, b, ldp ) truncate to integer, toward -infinity
186 * efrexp( a, exp, s ) extract exponent and significand
187 * eifrac( e, &l, frac ) e to long integer and e type fraction
188 * euifrac( e, &l, frac ) e to unsigned long integer and e type fraction
189 * einfin( e, ldp ) set e to infinity, leaving its sign alone
190 * eldexp( a, n, b ) multiply by 2**n
192 * emul( a, b, c, ldp ) c = b * a
194 * eround( a, b ) b = nearest integer value to a
195 * esub( a, b, c, ldp ) c = b - a
196 * e24toasc( &f, str, n ) single to ASCII string, n digits after decimal
197 * e53toasc( &d, str, n ) double to ASCII string, n digits after decimal
198 * e64toasc( &d, str, n ) long double to ASCII string
199 * etoasc(e,str,n,fmt,ldp)e to ASCII string, n digits after decimal
200 * etoe24( e, &f ) convert e type to IEEE single precision
201 * etoe53( e, &d ) convert e type to IEEE double precision
202 * etoe64( e, &d ) convert e type to IEEE long double precision
203 * ltoe( &l, e ) long (32 bit) integer to e type
204 * ultoe( &l, e ) unsigned long (32 bit) integer to e type
205 * eisneg( e ) 1 if sign bit of e != 0, else 0
206 * eisinf( e ) 1 if e has maximum exponent (non-IEEE)
207 * or is infinite (IEEE)
208 * eisnan( e ) 1 if e is a NaN
209 * esqrt( a, b ) b = square root of a
212 * Routines for internal format numbers
214 * eaddm( ai, bi ) add significands, bi = bi + ai
216 * ecleazs(ei) set ei = 0 but leave its sign alone
217 * ecmpm( ai, bi ) compare significands, return 1, 0, or -1
218 * edivm( ai, bi, ldp ) divide significands, bi = bi / ai
219 * emdnorm(ai,l,s,exp,ldp) normalize and round off
220 * emovi( a, ai ) convert external a to internal ai
221 * emovo( ai, a, ldp ) convert internal ai to external a
222 * emovz( ai, bi ) bi = ai, low guard word of bi = 0
223 * emulm( ai, bi, ldp ) multiply significands, bi = bi * ai
224 * enormlz(ei) left-justify the significand
225 * eshdn1( ai ) shift significand and guards down 1 bit
226 * eshdn8( ai ) shift down 8 bits
227 * eshdn6( ai ) shift down 16 bits
228 * eshift( ai, n ) shift ai n bits up (or down if n < 0)
229 * eshup1( ai ) shift significand and guards up 1 bit
230 * eshup8( ai ) shift up 8 bits
231 * eshup6( ai ) shift up 16 bits
232 * esubm( ai, bi ) subtract significands, bi = bi - ai
235 * The result is always normalized and rounded to NI-4 word precision
236 * after each arithmetic operation.
238 * Exception flags are NOT fully supported.
240 * Define INFINITY in mconf.h for support of infinity; otherwise a
241 * saturation arithmetic is implemented.
243 * Define NANS for support of Not-a-Number items; otherwise the
244 * arithmetic will never produce a NaN output, and might be confused
246 * If NaN's are supported, the output of ecmp(a,b) is -2 if
247 * either a or b is a NaN. This means asking if(ecmp(a,b) < 0)
248 * may not be legitimate. Use if(ecmp(a,b) == -1) for less-than
250 * Signaling NaN's are NOT supported; they are treated the same
253 * Denormals are always supported here where appropriate (e.g., not
254 * for conversion to DEC numbers).
260 * 5 Jan 84 PDP-11 assembly language version
261 * 6 Dec 86 C language version
262 * 30 Aug 88 100 digit version, improved rounding
263 * 15 May 92 80-bit long double support
264 * 22 Nov 00 Revised to fit into newlib by Jeff Johnston <jjohnstn@redhat.com>
266 * Author: S. L. Moshier.
268 * Copyright (c) 1984,2000 S.L. Moshier
270 * Permission to use, copy, modify, and distribute this software for any
271 * purpose without fee is hereby granted, provided that this entire notice
272 * is included in all copies of any software which is or includes a copy
273 * or modification of this software and in all copies of the supporting
274 * documentation for such software.
276 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
277 * WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION
278 * OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
279 * SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
284 /* #include "\usr\include\stdio.h" */
285 /*#include "ehead.h"*/
286 /*#include "mconf.h"*/
289 * Common include file for math routines
301 * This file contains definitions for error codes that are
302 * passed to the common error handling routine mtherr()
305 * The file also includes a conditional assembly definition
306 * for the type of computer arithmetic (IEEE, DEC, Motorola
309 * For Digital Equipment PDP-11 and VAX computers, certain
310 * IBM systems, and others that use numbers with a 56-bit
311 * significand, the symbol DEC should be defined. In this
312 * mode, most floating point constants are given as arrays
313 * of octal integers to eliminate decimal to binary conversion
314 * errors that might be introduced by the compiler.
316 * For computers, such as IBM PC, that follow the IEEE
317 * Standard for Binary Floating Point Arithmetic (ANSI/IEEE
318 * Std 754-1985), the symbol IBMPC should be defined. These
319 * numbers have 53-bit significands. In this mode, constants
320 * are provided as arrays of hexadecimal 16 bit integers.
322 * To accommodate other types of computer arithmetic, all
323 * constants are also provided in a normal decimal radix
324 * which one can hope are correctly converted to a suitable
325 * format by the available C language compiler. To invoke
326 * this mode, the symbol UNK is defined.
328 * An important difference among these modes is a predefined
329 * set of machine arithmetic constants for each. The numbers
330 * MACHEP (the machine roundoff error), MAXNUM (largest number
331 * represented), and several other parameters are preset by
332 * the configuration symbol. Check the file const.c to
333 * ensure that these values are correct for your computer.
335 * For ANSI C compatibility, define ANSIC equal to 1. Currently
336 * this affects only the atan2() function and others that use it.
339 /* Constant definitions for math error conditions
342 #define DOMAIN 1 /* argument domain error */
343 #define SING 2 /* argument singularity */
344 #define OVERFLOW 3 /* overflow range error */
345 #define UNDERFLOW 4 /* underflow range error */
346 #define TLOSS 5 /* total loss of precision */
347 #define PLOSS 6 /* partial loss of precision */
358 /* Type of computer arithmetic */
361 #ifdef __IEEE_LITTLE_ENDIAN
363 #else /* !__IEEE_LITTLE_ENDIAN */
365 #endif /* !__IEEE_LITTLE_ENDIAN */
368 /* Define 1 for ANSI C atan2() function
369 * See atan.c and clog.c.
373 /*define VOLATILE volatile*/
379 /* NaN's require infinity support. */
386 /* This handles 64-bit long ints. */
387 #define LONGBITS (8 * sizeof(long))
390 static void eaddm(short unsigned int *x
, short unsigned int *y
);
391 static void esubm(short unsigned int *x
, short unsigned int *y
);
392 static void emdnorm(short unsigned int *s
, int lost
, int subflg
, long int exp
, int rcntrl
, LDPARMS
*ldp
);
393 static int asctoeg(char *ss
, short unsigned int *y
, int oprec
, LDPARMS
*ldp
);
394 static void enan(short unsigned int *nan
, int size
);
395 #if SIMD_LDBL_MANT_DIG == 24
396 static void toe24(short unsigned int *x
, short unsigned int *y
);
397 #elif SIMD_LDBL_MANT_DIG == 53
398 static void toe53(short unsigned int *x
, short unsigned int *y
);
399 #elif SIMD_LDBL_MANT_DIG == 64
400 static void toe64(short unsigned int *a
, short unsigned int *b
);
402 static void toe113(short unsigned int *a
, short unsigned int *b
);
404 static void eiremain(short unsigned int *den
, short unsigned int *num
, LDPARMS
*ldp
);
405 static int ecmpm(register short unsigned int *a
, register short unsigned int *b
);
406 static int edivm(short unsigned int *den
, short unsigned int *num
, LDPARMS
*ldp
);
407 static int emulm(short unsigned int *a
, short unsigned int *b
, LDPARMS
*ldp
);
408 static int eisneg(short unsigned int *x
);
409 static int eisinf(short unsigned int *x
);
410 static void emovi(short unsigned int *a
, short unsigned int *b
);
411 static void emovo(short unsigned int *a
, short unsigned int *b
, LDPARMS
*ldp
);
412 static void emovz(register short unsigned int *a
, register short unsigned int *b
);
413 static void ecleaz(register short unsigned int *xi
);
414 static void eadd1(short unsigned int *a
, short unsigned int *b
, short unsigned int *c
, int subflg
, LDPARMS
*ldp
);
415 static int eisnan(short unsigned int *x
);
416 static int eiisnan(short unsigned int *x
);
419 static void etodec(), todec(), dectoe();
423 ; Clear out entire external format number.
425 ; unsigned short x[];
429 static void eclear(register short unsigned int *x
)
433 for( i
=0; i
<NE
; i
++ )
439 /* Move external format number from a to b.
444 static void emov(register short unsigned int *a
, register short unsigned int *b
)
448 for( i
=0; i
<NE
; i
++ )
454 ; Negate external format number
456 ; unsigned short x[NE];
460 static void eneg(short unsigned int *x
)
467 x
[NE
-1] ^= 0x8000; /* Toggle the sign bit */
472 /* Return 1 if external format number is negative,
475 static int eisneg(short unsigned int *x
)
482 if( x
[NE
-1] & 0x8000 )
489 /* Return 1 if external format number has maximum possible exponent,
492 static int eisinf(short unsigned int *x
)
495 if( (x
[NE
-1] & 0x7fff) == 0x7fff )
507 /* Check if e-type number is not a number.
509 static int eisnan(short unsigned int *x
)
514 /* NaN has maximum exponent */
515 if( (x
[NE
-1] & 0x7fff) != 0x7fff )
517 /* ... and non-zero significand field. */
518 for( i
=0; i
<NE
-1; i
++ )
528 ; Fill entire number, including exponent and significand, with
529 ; largest possible number. These programs implement a saturation
530 ; value that is an ordinary, legal number. A special value
531 ; "infinity" may also be implemented; this would require tests
532 ; for that value and implementation of special rules for arithmetic
533 ; operations involving inifinity.
536 static void einfin(register short unsigned int *x
, register LDPARMS
*ldp
)
541 for( i
=0; i
<NE
-1; i
++ )
546 for( i
=0; i
<NE
-1; i
++ )
549 if( ldp
->rndprc
< NBITS
)
551 if (ldp
->rndprc
== 113)
556 if( ldp
->rndprc
== 64 )
560 if( ldp
->rndprc
== 53 )
574 /* Move in external format number,
575 * converting it to internal format.
577 static void emovi(short unsigned int *a
, short unsigned int *b
)
579 register unsigned short *p
, *q
;
583 p
= a
+ (NE
-1); /* point to last word of external number */
584 /* get the sign bit */
589 /* get the exponent */
591 *q
++ &= 0x7fff; /* delete the sign bit */
593 if( (*(q
-1) & 0x7fff) == 0x7fff )
599 for( i
=3; i
<NI
; i
++ )
604 for( i
=2; i
<NI
; i
++ )
609 /* clear high guard word */
611 /* move in the significand */
612 for( i
=0; i
<NE
-1; i
++ )
614 /* clear low guard word */
619 /* Move internal format number out,
620 * converting it to external format.
622 static void emovo(short unsigned int *a
, short unsigned int *b
, LDPARMS
*ldp
)
624 register unsigned short *p
, *q
;
628 q
= b
+ (NE
-1); /* point to output exponent */
629 /* combine sign and exponent */
632 *q
-- = *p
++ | 0x8000;
636 if( *(p
-1) == 0x7fff )
649 /* skip over guard word */
651 /* move the significand */
652 for( i
=0; i
<NE
-1; i
++ )
657 /* Clear out internal format number.
660 static void ecleaz(register short unsigned int *xi
)
664 for( i
=0; i
<NI
; i
++ )
668 /* same, but don't touch the sign. */
670 static void ecleazs(register short unsigned int *xi
)
675 for(i
=0; i
<NI
-1; i
++)
682 /* Move internal format number from a to b.
684 static void emovz(register short unsigned int *a
, register short unsigned int *b
)
688 for( i
=0; i
<NI
-1; i
++ )
690 /* clear low guard word */
694 /* Return nonzero if internal format number is a NaN.
697 static int eiisnan (short unsigned int *x
)
701 if( (x
[E
] & 0x7fff) == 0x7fff )
703 for( i
=M
+1; i
<NI
; i
++ )
712 #if SIMD_LDBL_MANT_DIG == 64
714 /* Return nonzero if internal format number is infinite. */
724 if ((x
[E
] & 0x7fff) == 0x7fff)
728 #endif /* SIMD_LDBL_MANT_DIG == 64 */
731 ; Compare significands of numbers in internal format.
732 ; Guard words are included in the comparison.
734 ; unsigned short a[NI], b[NI];
737 ; for the significands:
738 ; returns +1 if a > b
742 static int ecmpm(register short unsigned int *a
, register short unsigned int *b
)
746 a
+= M
; /* skip up to significand area */
748 for( i
=M
; i
<NI
; i
++ )
756 if( *(--a
) > *(--b
) )
764 ; Shift significand down by 1 bit
767 static void eshdn1(register short unsigned int *x
)
769 register unsigned short bits
;
772 x
+= M
; /* point to significand area */
775 for( i
=M
; i
<NI
; i
++ )
790 ; Shift significand up by 1 bit
793 static void eshup1(register short unsigned int *x
)
795 register unsigned short bits
;
801 for( i
=M
; i
<NI
; i
++ )
816 ; Shift significand down by 8 bits
819 static void eshdn8(register short unsigned int *x
)
821 register unsigned short newbyt
, oldbyt
;
826 for( i
=M
; i
<NI
; i
++ )
837 ; Shift significand up by 8 bits
840 static void eshup8(register short unsigned int *x
)
843 register unsigned short newbyt
, oldbyt
;
848 for( i
=M
; i
<NI
; i
++ )
859 ; Shift significand up by 16 bits
862 static void eshup6(register short unsigned int *x
)
865 register unsigned short *p
;
870 for( i
=M
; i
<NI
-1; i
++ )
877 ; Shift significand down by 16 bits
880 static void eshdn6(register short unsigned int *x
)
883 register unsigned short *p
;
888 for( i
=M
; i
<NI
-1; i
++ )
899 static void eaddm(short unsigned int *x
, short unsigned int *y
)
901 register unsigned long a
;
908 for( i
=M
; i
<NI
; i
++ )
910 a
= (unsigned long )(*x
) + (unsigned long )(*y
) + carry
;
915 *y
= (unsigned short )a
;
922 ; Subtract significands
926 static void esubm(short unsigned int *x
, short unsigned int *y
)
935 for( i
=M
; i
<NI
; i
++ )
937 a
= (unsigned long )(*y
) - (unsigned long )(*x
) - carry
;
942 *y
= (unsigned short )a
;
949 /* Divide significands */
952 /* Multiply significand of e-type number b
953 by 16-bit quantity a, e-type result to c. */
955 static void m16m(short unsigned int a
, short unsigned int *b
, short unsigned int *c
)
957 register unsigned short *pp
;
958 register unsigned long carry
;
960 unsigned short p
[NI
];
970 for( i
=M
+1; i
<NI
; i
++ )
980 m
= (unsigned long) aa
* *ps
--;
981 carry
= (m
& 0xffff) + *pp
;
982 *pp
-- = (unsigned short )carry
;
983 carry
= (carry
>> 16) + (m
>> 16) + *pp
;
984 *pp
= (unsigned short )carry
;
985 *(pp
-1) = carry
>> 16;
988 for( i
=M
; i
<NI
; i
++ )
993 /* Divide significands. Neither the numerator nor the denominator
994 is permitted to have its high guard word nonzero. */
997 static int edivm(short unsigned int *den
, short unsigned int *num
, LDPARMS
*ldp
)
1000 register unsigned short *p
;
1002 unsigned short j
, tdenm
, tquot
;
1003 unsigned short tprod
[NI
+1];
1004 unsigned short *equot
= ldp
->equot
;
1010 for( i
=M
; i
<NI
; i
++ )
1016 for( i
=M
; i
<NI
; i
++ )
1018 /* Find trial quotient digit (the radix is 65536). */
1019 tnum
= (((unsigned long) num
[M
]) << 16) + num
[M
+1];
1021 /* Do not execute the divide instruction if it will overflow. */
1022 if( (tdenm
* 0xffffUL
) < tnum
)
1025 tquot
= tnum
/ tdenm
;
1027 /* Prove that the divide worked. */
1029 tcheck = (unsigned long )tquot * tdenm;
1030 if( tnum - tcheck > tdenm )
1033 /* Multiply denominator by trial quotient digit. */
1034 m16m( tquot
, den
, tprod
);
1035 /* The quotient digit may have been overestimated. */
1036 if( ecmpm( tprod
, num
) > 0 )
1039 esubm( den
, tprod
);
1040 if( ecmpm( tprod
, num
) > 0 )
1043 esubm( den
, tprod
);
1047 if( ecmpm( tprod, num ) > 0 )
1049 eshow( "tprod", tprod );
1050 eshow( "num ", num );
1051 printf( "tnum = %08lx, tden = %04x, tquot = %04x\n",
1052 tnum, den[M+1], tquot );
1055 esubm( tprod
, num
);
1057 if( ecmpm( num, den ) >= 0 )
1059 eshow( "num ", num );
1060 eshow( "den ", den );
1061 printf( "tnum = %08lx, tden = %04x, tquot = %04x\n",
1062 tnum, den[M+1], tquot );
1068 /* test for nonzero remainder after roundoff bit */
1071 for( i
=M
; i
<NI
; i
++ )
1078 for( i
=0; i
<NI
; i
++ )
1086 /* Multiply significands */
1087 static int emulm(short unsigned int *a
, short unsigned int *b
, LDPARMS
*ldp
)
1089 unsigned short *p
, *q
;
1090 unsigned short pprod
[NI
];
1093 unsigned short *equot
= ldp
->equot
;
1097 for( i
=M
; i
<NI
; i
++ )
1103 for( i
=M
+1; i
<NI
; i
++ )
1111 m16m( *p
--, b
, pprod
);
1112 eaddm(pprod
, equot
);
1118 for( i
=0; i
<NI
; i
++ )
1121 /* return flag for lost nonzero bits */
1127 static void eshow(str, x)
1133 printf( "%s ", str );
1134 for( i=0; i<NI; i++ )
1135 printf( "%04x ", *x++ );
1142 * Normalize and round off.
1144 * The internal format number to be rounded is "s".
1145 * Input "lost" indicates whether the number is exact.
1146 * This is the so-called sticky bit.
1148 * Input "subflg" indicates whether the number was obtained
1149 * by a subtraction operation. In that case if lost is nonzero
1150 * then the number is slightly smaller than indicated.
1152 * Input "exp" is the biased exponent, which may be negative.
1153 * the exponent field of "s" is ignored but is replaced by
1154 * "exp" as adjusted by normalization and rounding.
1156 * Input "rcntrl" is the rounding control.
1160 static void emdnorm(short unsigned int *s
, int lost
, int subflg
, long int exp
, int rcntrl
, LDPARMS
*ldp
)
1168 /* a blank significand could mean either zero or infinity. */
1181 if( (j
> NBITS
) && (exp
< 32767L) )
1189 if( exp
> (long )(-NBITS
-1) )
1202 /* Round off, unless told not to by rcntrl. */
1205 /* Set up rounding parameters if the control register changed. */
1206 if( ldp
->rndprc
!= ldp
->rlast
)
1208 ecleaz( ldp
->rbit
);
1209 switch( ldp
->rndprc
)
1213 ldp
->rw
= NI
-1; /* low guard word */
1215 ldp
->rmbit
= 0x8000;
1217 ldp
->re
= ldp
->rw
- 1;
1222 ldp
->rmbit
= 0x4000;
1223 ldp
->rebit
= 0x8000;
1229 ldp
->rmbit
= 0x8000;
1231 ldp
->re
= ldp
->rw
-1;
1233 /* For DEC arithmetic */
1244 ldp
->rmbit
= 0x0400;
1256 ldp
->rbit
[ldp
->re
] = ldp
->rebit
;
1257 ldp
->rlast
= ldp
->rndprc
;
1260 /* Shift down 1 temporarily if the data structure has an implied
1261 * most significant bit and the number is denormal.
1262 * For rndprc = 64 or NBITS, there is no implied bit.
1263 * But Intel long double denormals lose one bit of significance even so.
1266 if( (exp
<= 0) && (ldp
->rndprc
!= NBITS
) )
1268 if( (exp
<= 0) && (ldp
->rndprc
!= 64) && (ldp
->rndprc
!= NBITS
) )
1271 lost
|= s
[NI
-1] & 1;
1274 /* Clear out all bits below the rounding bit,
1275 * remembering in r if any were nonzero.
1277 r
= s
[ldp
->rw
] & ldp
->rmsk
;
1278 if( ldp
->rndprc
< NBITS
)
1289 s
[ldp
->rw
] &= ~ldp
->rmsk
;
1290 if( (r
& ldp
->rmbit
) != 0 )
1292 if( r
== ldp
->rmbit
)
1295 { /* round to even */
1296 if( (s
[ldp
->re
] & ldp
->rebit
) == 0 )
1305 eaddm( ldp
->rbit
, s
);
1309 if( (exp
<= 0) && (ldp
->rndprc
!= NBITS
) )
1311 if( (exp
<= 0) && (ldp
->rndprc
!= 64) && (ldp
->rndprc
!= NBITS
) )
1317 { /* overflow on roundoff */
1330 for( i
=2; i
<NI
-1; i
++ )
1335 for( i
=M
+1; i
<NI
-1; i
++ )
1338 if( (ldp
->rndprc
< 64) || (ldp
->rndprc
== 113) )
1340 s
[ldp
->rw
] &= ~ldp
->rmsk
;
1341 if( ldp
->rndprc
== 24 )
1353 s
[1] = (unsigned short )exp
;
1359 ; Subtract external format numbers.
1361 ; unsigned short a[NE], b[NE], c[NE];
1363 ; esub( a, b, c, ldp ); c = b - a
1366 static void esub(short unsigned int *a
, short unsigned int *b
, short unsigned int *c
, LDPARMS
*ldp
)
1380 /* Infinity minus infinity is a NaN.
1381 * Test for subtracting infinities of the same sign.
1383 if( eisinf(a
) && eisinf(b
) && ((eisneg (a
) ^ eisneg (b
)) == 0))
1385 mtherr( "esub", DOMAIN
);
1390 eadd1( a
, b
, c
, 1, ldp
);
1395 static void eadd1(short unsigned int *a
, short unsigned int *b
, short unsigned int *c
, int subflg
, LDPARMS
*ldp
)
1397 unsigned short ai
[NI
], bi
[NI
], ci
[NI
];
1420 /* compare exponents */
1425 { /* put the larger number in bi */
1435 if( lt
< (long )(-NBITS
-1) )
1436 goto done
; /* answer same as larger addend */
1438 lost
= eshift( ai
, k
); /* shift the smaller number down */
1442 /* exponents were the same, so must compare significands */
1443 i
= ecmpm( ai
, bi
);
1445 { /* the numbers are identical in magnitude */
1446 /* if different signs, result is zero */
1447 if( ai
[0] != bi
[0] )
1452 /* if same sign, result is double */
1453 /* double denomalized tiny number */
1454 if( (bi
[E
] == 0) && ((bi
[3] & 0x8000) == 0) )
1459 /* add 1 to exponent unless both are zero! */
1460 for( j
=1; j
<NI
-1; j
++ )
1464 /* This could overflow, but let emovo take care of that. */
1469 bi
[E
] = (unsigned short )ltb
;
1473 { /* put the larger number in bi */
1479 if( ai
[0] == bi
[0] )
1489 emdnorm( bi
, lost
, subflg
, ltb
, 64, ldp
);
1492 emovo( bi
, c
, ldp
);
1500 ; unsigned short a[NE], b[NE], c[NE];
1502 ; ediv( a, b, c, ldp ); c = b / a
1504 static void ediv(short unsigned int *a
, short unsigned int *b
, short unsigned int *c
, LDPARMS
*ldp
)
1506 unsigned short ai
[NI
], bi
[NI
];
1511 /* Return any NaN input. */
1522 /* Zero over zero, or infinity over infinity, is a NaN. */
1523 if( ((ecmp(a
,ezero
) == 0) && (ecmp(b
,ezero
) == 0))
1524 || (eisinf (a
) && eisinf (b
)) )
1526 mtherr( "ediv", DOMAIN
);
1531 /* Infinity over anything else is infinity. */
1535 if( eisneg(a
) ^ eisneg(b
) )
1536 *(c
+(NE
-1)) = 0x8000;
1553 { /* See if numerator is zero. */
1554 for( i
=1; i
<NI
-1; i
++ )
1558 ltb
-= enormlz( bi
);
1568 { /* possible divide by zero */
1569 for( i
=1; i
<NI
-1; i
++ )
1573 lta
-= enormlz( ai
);
1577 if( ai
[0] == bi
[0] )
1580 *(c
+(NE
-1)) = 0x8000;
1582 mtherr( "ediv", SING
);
1587 i
= edivm( ai
, bi
, ldp
);
1588 /* calculate exponent */
1589 lt
= ltb
- lta
+ EXONE
;
1590 emdnorm( bi
, i
, 0, lt
, 64, ldp
);
1592 if( ai
[0] == bi
[0] )
1596 emovo( bi
, c
, ldp
);
1604 ; unsigned short a[NE], b[NE], c[NE];
1606 ; emul( a, b, c, ldp ); c = b * a
1608 static void emul(short unsigned int *a
, short unsigned int *b
, short unsigned int *c
, LDPARMS
*ldp
)
1610 unsigned short ai
[NI
], bi
[NI
];
1615 /* NaN times anything is the same NaN. */
1626 /* Zero times infinity is a NaN. */
1627 if( (eisinf(a
) && (ecmp(b
,ezero
) == 0))
1628 || (eisinf(b
) && (ecmp(a
,ezero
) == 0)) )
1630 mtherr( "emul", DOMAIN
);
1635 /* Infinity times anything else is infinity. */
1637 if( eisinf(a
) || eisinf(b
) )
1639 if( eisneg(a
) ^ eisneg(b
) )
1640 *(c
+(NE
-1)) = 0x8000;
1653 for( i
=1; i
<NI
-1; i
++ )
1657 lta
-= enormlz( ai
);
1668 for( i
=1; i
<NI
-1; i
++ )
1672 ltb
-= enormlz( bi
);
1681 /* Multiply significands */
1682 j
= emulm( ai
, bi
, ldp
);
1683 /* calculate exponent */
1684 lt
= lta
+ ltb
- (EXONE
- 1);
1685 emdnorm( bi
, j
, 0, lt
, 64, ldp
);
1686 /* calculate sign of product */
1687 if( ai
[0] == bi
[0] )
1691 emovo( bi
, c
, ldp
);
1696 #if SIMD_LDBL_MANT_DIG > 64
1697 static void e113toe(short unsigned int *pe
, short unsigned int *y
, LDPARMS
*ldp
)
1699 register unsigned short r
;
1700 unsigned short *e
, *p
;
1701 unsigned short yy
[NI
];
1720 for( i
=0; i
<7; i
++ )
1729 for( i
=1; i
<8; i
++ )
1745 #endif /* INFINITY */
1749 for( i
=0; i
<7; i
++ )
1753 for( i
=0; i
<7; i
++ )
1756 /* If denormal, remove the implied bit; else shift down 1. */
1769 /* move out internal format to ieee long double */
1770 static void toe113(short unsigned int *a
, short unsigned int *b
)
1772 register unsigned short *p
, *q
;
1786 q
= b
+ 7; /* point to output exponent */
1789 /* If not denormal, delete the implied bit. */
1794 /* combine sign and exponent */
1798 *q
++ = *p
++ | 0x8000;
1803 *q
-- = *p
++ | 0x8000;
1807 /* skip over guard word */
1809 /* move the significand */
1811 for (i
= 0; i
< 7; i
++)
1814 for (i
= 0; i
< 7; i
++)
1818 #endif /* SIMD_LDBL_MANT_DIG > 64 */
1821 #if SIMD_LDBL_MANT_DIG == 64
1822 static void e64toe(short unsigned int *pe
, short unsigned int *y
, LDPARMS
*ldp
)
1824 unsigned short yy
[NI
];
1825 unsigned short *p
, *q
, *e
;
1831 for( i
=0; i
<NE
-5; i
++ )
1834 for( i
=0; i
<5; i
++ )
1838 for( i
=0; i
<5; i
++ )
1842 p
= &yy
[0] + (NE
-1);
1844 ++e
; /* MIEEE skips over 2nd short */
1845 for( i
=0; i
<4; i
++ )
1850 /* For Intel long double, shift denormal significand up 1
1851 -- but only if the top significand bit is zero. */
1852 if((yy
[NE
-1] & 0x7fff) == 0 && (yy
[NE
-2] & 0x8000) == 0)
1854 unsigned short temp
[NI
+1];
1862 /* Point to the exponent field. */
1868 for( i
=0; i
<4; i
++ )
1870 if((i
!= 3 && pe
[i
] != 0)
1871 /* Check for Intel long double infinity pattern. */
1872 || (i
== 3 && pe
[i
] != 0x8000))
1880 for( i
=2; i
<=5; i
++ )
1896 #endif /* INFINITY */
1899 for( i
=0; i
<NE
; i
++ )
1903 /* move out internal format to ieee long double */
1904 static void toe64(short unsigned int *a
, short unsigned int *b
)
1906 register unsigned short *p
, *q
;
1917 /* Shift Intel denormal significand down 1. */
1925 q
= b
+ 4; /* point to output exponent */
1926 /* NOTE: Intel data type is 96 bits wide, clear the last word here. */
1930 /* combine sign and exponent */
1934 *q
++ = *p
++ | 0x8000;
1937 *q
++ = 0; /* leave 2nd short blank */
1940 *q
-- = *p
++ | 0x8000;
1944 /* skip over guard word */
1946 /* move the significand */
1948 for( i
=0; i
<4; i
++ )
1955 /* Intel long double infinity. */
1963 #endif /* INFINITY */
1964 for( i
=0; i
<4; i
++ )
1969 #endif /* SIMD_LDBL_MANT_DIG == 64 */
1971 #if SIMD_LDBL_MANT_DIG == 53
1973 ; Convert IEEE double precision to e type
1975 ; unsigned short x[N+2];
1978 static void e53toe(short unsigned int *pe
, short unsigned int *y
, LDPARMS
*ldp
)
1982 dectoe( pe
, y
); /* see etodec.c */
1986 register unsigned short r
;
1987 register unsigned short *p
, *e
;
1988 unsigned short yy
[NI
];
1992 denorm
= 0; /* flag if denormalized number */
2004 yy
[M
] = (r
& 0x0f) | 0x10;
2005 r
&= ~0x800f; /* strip sign and 4 significand bits */
2011 if( ((pe
[3] & 0xf) != 0) || (pe
[2] != 0)
2012 || (pe
[1] != 0) || (pe
[0] != 0) )
2018 if( ((pe
[0] & 0xf) != 0) || (pe
[1] != 0)
2019 || (pe
[2] != 0) || (pe
[3] != 0) )
2034 /* If zero exponent, then the significand is denormalized.
2035 * So, take back the understood high significand bit. */
2054 (void )eshift( yy
, -5 );
2056 { /* if zero exponent, then normalize the significand */
2057 if( (k
= enormlz(yy
)) > NBITS
)
2060 yy
[E
] -= (unsigned short )(k
-1);
2062 emovo( yy
, y
, ldp
);
2067 ; e type to IEEE double precision
2069 ; unsigned short x[NE];
2075 static void etoe53( x
, e
)
2076 unsigned short *x
, *e
;
2078 etodec( x
, e
); /* see etodec.c */
2081 static void toe53( x
, y
)
2082 unsigned short *x
, *y
;
2089 static void toe53(short unsigned int *x
, short unsigned int *y
)
2109 *y
= 0; /* output high order */
2111 *y
= 0x8000; /* output sign bit */
2114 if( i
>= (unsigned int )2047 )
2115 { /* Saturate at largest number less than infinity. */
2128 #else /* !INFINITY */
2129 *y
|= (unsigned short )0x7fef;
2140 #endif /* !INFINITY */
2145 (void )eshift( x
, 4 );
2150 (void )eshift( x
, 5 );
2152 i
|= *p
++ & (unsigned short )0x0f; /* *p = xi[M] */
2153 *y
|= (unsigned short )i
; /* high order output already has sign bit set */
2166 #endif /* not DEC */
2167 #endif /* SIMD_LDBL_MANT_DIG == 53 */
2169 #if SIMD_LDBL_MANT_DIG == 24
2171 ; Convert IEEE single precision to e type
2173 ; unsigned short x[N+2];
2176 void e24toe( short unsigned int *pe
, short unsigned int *y
, LDPARMS
*ldp
)
2178 register unsigned short r
;
2179 register unsigned short *p
, *e
;
2180 unsigned short yy
[NI
];
2184 denorm
= 0; /* flag if denormalized number */
2196 yy
[M
] = (r
& 0x7f) | 0200;
2197 r
&= ~0x807f; /* strip sign and 7 significand bits */
2203 if( ((pe
[0] & 0x7f) != 0) || (pe
[1] != 0) )
2209 if( ((pe
[1] & 0x7f) != 0) || (pe
[0] != 0) )
2224 /* If zero exponent, then the significand is denormalized.
2225 * So, take back the understood high significand bit. */
2244 (void )eshift( yy
, -8 );
2246 { /* if zero exponent, then normalize the significand */
2247 if( (k
= enormlz(yy
)) > NBITS
)
2250 yy
[E
] -= (unsigned short )(k
-1);
2252 emovo( yy
, y
, ldp
);
2255 static void toe24(short unsigned int *x
, short unsigned int *y
)
2274 *y
= 0; /* output high order */
2276 *y
= 0x8000; /* output sign bit */
2280 { /* Saturate at largest number less than infinity. */
2282 *y
|= (unsigned short )0x7f80;
2293 #else /* !INFINITY */
2294 *y
|= (unsigned short )0x7f7f;
2305 #endif /* !INFINITY */
2310 (void )eshift( x
, 7 );
2315 (void )eshift( x
, 8 );
2317 i
|= *p
++ & (unsigned short )0x7f; /* *p = xi[M] */
2318 *y
|= i
; /* high order output already has sign bit set */
2330 #endif /* SIMD_LDBL_MANT_DIG == 24 */
2332 /* Compare two e type numbers.
2334 * unsigned short a[NE], b[NE];
2337 * returns +1 if a > b
2340 * -2 if either a or b is a NaN.
2342 static int ecmp(short unsigned int *a
, short unsigned int *b
)
2344 unsigned short ai
[NI
], bi
[NI
];
2345 register unsigned short *p
, *q
;
2350 if (eisnan (a
) || eisnan (b
))
2359 { /* the signs are different */
2361 for( i
=1; i
<NI
-1; i
++ )
2375 /* both are the same sign */
2390 return(0); /* equality */
2396 if( *(--p
) > *(--q
) )
2397 return( msign
); /* p is bigger */
2399 return( -msign
); /* p is littler */
2406 ; Shifts significand area up or down by the number of bits
2407 ; given by the variable sc.
2409 static int eshift(short unsigned int *x
, int sc
)
2411 unsigned short lost
;
2425 lost
|= *p
; /* remember lost bits */
2466 return( (int )lost
);
2474 ; Shift normalizes the significand area pointed to by argument
2475 ; shift count (up = positive) is returned.
2477 static int enormlz(short unsigned int *x
)
2479 register unsigned short *p
;
2488 return( 0 ); /* already normalized */
2493 /* With guard word, there are NBITS+16 bits available.
2494 * return true if all are zero.
2499 /* see if high byte is zero */
2500 while( (*p
& 0xff00) == 0 )
2505 /* now shift 1 bit at a time */
2506 while( (*p
& 0x8000) == 0)
2510 if( sc
> (NBITS
+16) )
2512 mtherr( "enormlz", UNDERFLOW
);
2518 /* Normalize by shifting down out of the high guard word
2519 of the significand */
2534 mtherr( "enormlz", OVERFLOW
);
2544 /* Convert e type number to decimal format ASCII string.
2545 * The constants are for 64 bit precision.
2552 static unsigned short etens
[NTEN
+ 1][NE
] =
2554 {0x6576, 0x4a92, 0x804a, 0x153f,
2555 0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,}, /* 10**4096 */
2556 {0x6a32, 0xce52, 0x329a, 0x28ce,
2557 0xa74d, 0x5de4, 0xc53d, 0x3b5d, 0x9e8b, 0x5a92,}, /* 10**2048 */
2558 {0x526c, 0x50ce, 0xf18b, 0x3d28,
2559 0x650d, 0x0c17, 0x8175, 0x7586, 0xc976, 0x4d48,},
2560 {0x9c66, 0x58f8, 0xbc50, 0x5c54,
2561 0xcc65, 0x91c6, 0xa60e, 0xa0ae, 0xe319, 0x46a3,},
2562 {0x851e, 0xeab7, 0x98fe, 0x901b,
2563 0xddbb, 0xde8d, 0x9df9, 0xebfb, 0xaa7e, 0x4351,},
2564 {0x0235, 0x0137, 0x36b1, 0x336c,
2565 0xc66f, 0x8cdf, 0x80e9, 0x47c9, 0x93ba, 0x41a8,},
2566 {0x50f8, 0x25fb, 0xc76b, 0x6b71,
2567 0x3cbf, 0xa6d5, 0xffcf, 0x1f49, 0xc278, 0x40d3,},
2568 {0x0000, 0x0000, 0x0000, 0x0000,
2569 0xf020, 0xb59d, 0x2b70, 0xada8, 0x9dc5, 0x4069,},
2570 {0x0000, 0x0000, 0x0000, 0x0000,
2571 0x0000, 0x0000, 0x0400, 0xc9bf, 0x8e1b, 0x4034,},
2572 {0x0000, 0x0000, 0x0000, 0x0000,
2573 0x0000, 0x0000, 0x0000, 0x2000, 0xbebc, 0x4019,},
2574 {0x0000, 0x0000, 0x0000, 0x0000,
2575 0x0000, 0x0000, 0x0000, 0x0000, 0x9c40, 0x400c,},
2576 {0x0000, 0x0000, 0x0000, 0x0000,
2577 0x0000, 0x0000, 0x0000, 0x0000, 0xc800, 0x4005,},
2578 {0x0000, 0x0000, 0x0000, 0x0000,
2579 0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,}, /* 10**1 */
2582 static unsigned short emtens
[NTEN
+ 1][NE
] =
2584 {0x2030, 0xcffc, 0xa1c3, 0x8123,
2585 0x2de3, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,}, /* 10**-4096 */
2586 {0x8264, 0xd2cb, 0xf2ea, 0x12d4,
2587 0x4925, 0x2de4, 0x3436, 0x534f, 0xceae, 0x256b,}, /* 10**-2048 */
2588 {0xf53f, 0xf698, 0x6bd3, 0x0158,
2589 0x87a6, 0xc0bd, 0xda57, 0x82a5, 0xa2a6, 0x32b5,},
2590 {0xe731, 0x04d4, 0xe3f2, 0xd332,
2591 0x7132, 0xd21c, 0xdb23, 0xee32, 0x9049, 0x395a,},
2592 {0xa23e, 0x5308, 0xfefb, 0x1155,
2593 0xfa91, 0x1939, 0x637a, 0x4325, 0xc031, 0x3cac,},
2594 {0xe26d, 0xdbde, 0xd05d, 0xb3f6,
2595 0xac7c, 0xe4a0, 0x64bc, 0x467c, 0xddd0, 0x3e55,},
2596 {0x2a20, 0x6224, 0x47b3, 0x98d7,
2597 0x3f23, 0xe9a5, 0xa539, 0xea27, 0xa87f, 0x3f2a,},
2598 {0x0b5b, 0x4af2, 0xa581, 0x18ed,
2599 0x67de, 0x94ba, 0x4539, 0x1ead, 0xcfb1, 0x3f94,},
2600 {0xbf71, 0xa9b3, 0x7989, 0xbe68,
2601 0x4c2e, 0xe15b, 0xc44d, 0x94be, 0xe695, 0x3fc9,},
2602 {0x3d4d, 0x7c3d, 0x36ba, 0x0d2b,
2603 0xfdc2, 0xcefc, 0x8461, 0x7711, 0xabcc, 0x3fe4,},
2604 {0xc155, 0xa4a8, 0x404e, 0x6113,
2605 0xd3c3, 0x652b, 0xe219, 0x1758, 0xd1b7, 0x3ff1,},
2606 {0xd70a, 0x70a3, 0x0a3d, 0xa3d7,
2607 0x3d70, 0xd70a, 0x70a3, 0x0a3d, 0xa3d7, 0x3ff8,},
2608 {0xcccd, 0xcccc, 0xcccc, 0xcccc,
2609 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3ffb,}, /* 10**-1 */
2612 static unsigned short etens
[NTEN
+1][NE
] = {
2613 {0xc94c,0x979a,0x8a20,0x5202,0xc460,0x7525,},/* 10**4096 */
2614 {0xa74d,0x5de4,0xc53d,0x3b5d,0x9e8b,0x5a92,},/* 10**2048 */
2615 {0x650d,0x0c17,0x8175,0x7586,0xc976,0x4d48,},
2616 {0xcc65,0x91c6,0xa60e,0xa0ae,0xe319,0x46a3,},
2617 {0xddbc,0xde8d,0x9df9,0xebfb,0xaa7e,0x4351,},
2618 {0xc66f,0x8cdf,0x80e9,0x47c9,0x93ba,0x41a8,},
2619 {0x3cbf,0xa6d5,0xffcf,0x1f49,0xc278,0x40d3,},
2620 {0xf020,0xb59d,0x2b70,0xada8,0x9dc5,0x4069,},
2621 {0x0000,0x0000,0x0400,0xc9bf,0x8e1b,0x4034,},
2622 {0x0000,0x0000,0x0000,0x2000,0xbebc,0x4019,},
2623 {0x0000,0x0000,0x0000,0x0000,0x9c40,0x400c,},
2624 {0x0000,0x0000,0x0000,0x0000,0xc800,0x4005,},
2625 {0x0000,0x0000,0x0000,0x0000,0xa000,0x4002,}, /* 10**1 */
2628 static unsigned short emtens
[NTEN
+1][NE
] = {
2629 {0x2de4,0x9fde,0xd2ce,0x04c8,0xa6dd,0x0ad8,}, /* 10**-4096 */
2630 {0x4925,0x2de4,0x3436,0x534f,0xceae,0x256b,}, /* 10**-2048 */
2631 {0x87a6,0xc0bd,0xda57,0x82a5,0xa2a6,0x32b5,},
2632 {0x7133,0xd21c,0xdb23,0xee32,0x9049,0x395a,},
2633 {0xfa91,0x1939,0x637a,0x4325,0xc031,0x3cac,},
2634 {0xac7d,0xe4a0,0x64bc,0x467c,0xddd0,0x3e55,},
2635 {0x3f24,0xe9a5,0xa539,0xea27,0xa87f,0x3f2a,},
2636 {0x67de,0x94ba,0x4539,0x1ead,0xcfb1,0x3f94,},
2637 {0x4c2f,0xe15b,0xc44d,0x94be,0xe695,0x3fc9,},
2638 {0xfdc2,0xcefc,0x8461,0x7711,0xabcc,0x3fe4,},
2639 {0xd3c3,0x652b,0xe219,0x1758,0xd1b7,0x3ff1,},
2640 {0x3d71,0xd70a,0x70a3,0x0a3d,0xa3d7,0x3ff8,},
2641 {0xcccd,0xcccc,0xcccc,0xcccc,0xcccc,0x3ffb,}, /* 10**-1 */
2647 /* ASCII string outputs for unix */
2651 void _IO_ldtostr(x
, string
, ndigs
, flags
, fmt
)
2658 unsigned short w
[NI
];
2661 LDPARMS
*ldp
= &rnd
;
2666 if (sizeof(long double) == 16)
2667 e113toe( (unsigned short *)x
, w
, ldp
);
2669 e64toe( (unsigned short *)x
, w
, ldp
);
2671 etoasc( w
, string
, ndigs
, -1, ldp
);
2672 if( ndigs
== 0 && flags
== 0 )
2674 /* Delete the decimal point unless alternate format. */
2700 /* This routine will not return more than NDEC+1 digits. */
2703 _simdldtoa_r (struct _reent
*ptr
, LONG_DOUBLE_UNION
*d
, int mode
, int ndigits
, int *decpt
,
2704 int *sign
, char **rve
)
2706 unsigned short e
[NI
];
2710 LDPARMS
*ldp
= &rnd
;
2716 _REENT_CHECK_MP(ptr
);
2718 /* reentrancy addition to use mprec storage pool */
2719 if (_REENT_MP_RESULT(ptr
))
2721 _REENT_MP_RESULT(ptr
)->_k
= _REENT_MP_RESULT_K(ptr
);
2722 _REENT_MP_RESULT(ptr
)->_maxwds
= 1 << _REENT_MP_RESULT_K(ptr
);
2723 Bfree (ptr
, _REENT_MP_RESULT(ptr
));
2724 _REENT_MP_RESULT(ptr
) = 0;
2727 #if SIMD_LDBL_MANT_DIG == 24
2728 e24toe( (unsigned short *)d
, e
, ldp
);
2729 #elif SIMD_LDBL_MANT_DIG == 53
2730 e53toe( (unsigned short *)d
, e
, ldp
);
2731 #elif SIMD_LDBL_MANT_DIG == 64
2732 e64toe( (unsigned short *)d
, e
, ldp
);
2734 e113toe( (unsigned short *)d
, e
, ldp
);
2741 /* Mode 3 is "f" format. */
2744 /* Mode 0 is for %.999 format, which is supposed to give a
2745 minimum length string that will convert back to the same binary value.
2746 For now, just ask for 20 digits which is enough but sometimes too many. */
2750 /* reentrancy addition to use mprec storage pool */
2751 /* we want to have enough space to hold the formatted result */
2752 i
= ndigits
+ (mode
== 3 ? (MAX_EXP_DIGITS
+ 1) : 1);
2753 j
= sizeof (__ULong
);
2754 for (_REENT_MP_RESULT_K(ptr
) = 0; sizeof (_Bigint
) - sizeof (__ULong
) + j
<= (unsigned)i
; j
<<= 1)
2755 _REENT_MP_RESULT_K(ptr
)++;
2756 _REENT_MP_RESULT(ptr
) = Balloc (ptr
, _REENT_MP_RESULT_K(ptr
));
2757 outstr
= (char *)_REENT_MP_RESULT(ptr
);
2759 /* This sanity limit must agree with the corresponding one in etoasc, to
2760 keep straight the returned value of outexpon. */
2761 if( ndigits
> NDEC
)
2764 etoasc( e
, outstr
, ndigits
, mode
, ldp
);
2766 if( eisinf(e
) || eisnan(e
) )
2771 *decpt
= ldp
->outexpon
+ 1;
2773 /* Transform the string returned by etoasc into what the caller wants. */
2775 /* Look for decimal point and delete it from the string. */
2787 /* Delete the decimal point. */
2796 /* Back up over the exponent field. */
2797 while( *s
!= 'E' && s
> outstr
)
2803 /* Strip leading spaces and sign. */
2805 while( *p
== ' ' || *p
== '-')
2808 /* Find new end of string. */
2810 while( (*s
++ = *p
++) != '\0' )
2814 /* Strip trailing zeros. */
2817 else if( ndigits
> ldp
->outexpon
)
2822 while( *(s
-1) == '0' && ((s
- outstr
) > k
))
2825 /* In f format, flush small off-scale values to zero.
2826 Rounding has been taken care of by etoasc. */
2827 if( mode
== 3 && ((ndigits
+ ldp
->outexpon
) < 0))
2839 /* Routine used to tell if long double is NaN or Infinity or regular number.
2840 Returns: 0 = regular number
2845 _simdldcheck (LONG_DOUBLE_UNION
*d
)
2847 unsigned short e
[NI
];
2849 LDPARMS
*ldp
= &rnd
;
2854 #if SIMD_LDBL_MANT_DIG == 24
2855 e24toe( (unsigned short *)d
, e
, ldp
);
2856 #elif SIMD_LDBL_MANT_DIG == 53
2857 e53toe( (unsigned short *)d
, e
, ldp
);
2858 #elif SIMD_LDBL_MANT_DIG == 64
2859 e64toe( (unsigned short *)d
, e
, ldp
);
2861 e113toe( (unsigned short *)d
, e
, ldp
);
2864 if( (e
[NE
-1] & 0x7fff) == 0x7fff )
2876 static void etoasc(short unsigned int *x
, char *string
, int ndigits
, int outformat
, LDPARMS
*ldp
)
2879 unsigned short y
[NI
], t
[NI
], u
[NI
], w
[NI
];
2880 unsigned short *p
, *r
, *ten
;
2881 unsigned short sign
;
2882 int i
, j
, k
, expon
, rndsav
, ndigs
;
2885 unsigned short *equot
= ldp
->equot
;
2888 rndsav
= ldp
->rndprc
;
2892 sprintf( string
, " NaN " );
2897 ldp
->rndprc
= NBITS
; /* set to full precision */
2898 emov( x
, y
); /* retain external format */
2899 if( y
[NE
-1] & 0x8000 )
2909 ten
= &etens
[NTEN
][0];
2911 /* Test for zero exponent */
2914 for( k
=0; k
<NE
-1; k
++ )
2917 goto tnzro
; /* denormalized number */
2919 goto isone
; /* legal all zeros */
2923 /* Test for infinity.
2925 if( y
[NE
-1] == 0x7fff )
2928 sprintf( string
, " -Infinity " );
2930 sprintf( string
, " Infinity " );
2935 /* Test for exponent nonzero but significand denormalized.
2936 * This is an error condition.
2938 if( (y
[NE
-1] != 0) && ((y
[NE
-2] & 0x8000) == 0) )
2940 mtherr( "etoasc", DOMAIN
);
2941 sprintf( string
, "NaN" );
2946 /* Compare to 1.0 */
2947 i
= ecmp( eone
, y
);
2952 { /* Number is greater than 1 */
2953 /* Convert significand to an integer and strip trailing decimal zeros. */
2955 u
[NE
-1] = EXONE
+ NBITS
- 1;
2957 p
= &etens
[NTEN
-4][0];
2961 ediv( p
, u
, t
, ldp
);
2962 efloor( t
, w
, ldp
);
2963 for( j
=0; j
<NE
-1; j
++ )
2976 /* Rescale from integer significand */
2977 u
[NE
-1] += y
[NE
-1] - (unsigned int )(EXONE
+ NBITS
- 1);
2979 /* Find power of 10 */
2983 while( ecmp( ten
, u
) <= 0 )
2985 if( ecmp( p
, u
) <= 0 )
2987 ediv( p
, u
, u
, ldp
);
2988 emul( p
, t
, t
, ldp
);
2998 { /* Number is less than 1.0 */
2999 /* Pad significand with trailing decimal zeros. */
3002 while( (y
[NE
-2] & 0x8000) == 0 )
3004 emul( ten
, y
, y
, ldp
);
3011 for( i
=0; i
<NDEC
+1; i
++ )
3013 if( (w
[NI
-1] & 0x7) != 0 )
3015 /* multiply by 10 */
3028 if( eone
[NE
-1] <= u
[1] )
3040 while( ecmp( eone
, w
) > 0 )
3042 if( ecmp( p
, w
) >= 0 )
3044 emul( r
, w
, w
, ldp
);
3045 emul( r
, t
, t
, ldp
);
3054 ediv( t
, eone
, t
, ldp
);
3057 /* Find the first (leading) digit. */
3062 eiremain( t
, y
, ldp
);
3063 digit
= equot
[NI
-1];
3064 while( (digit
== 0) && (ecmp(y
,ezero
) != 0) )
3071 eiremain( t
, y
, ldp
);
3072 digit
= equot
[NI
-1];
3080 /* Examine number of digits requested by caller. */
3081 if( outformat
== 3 )
3084 else if( ndigs < 0 )
3107 *s
++ = (char )digit
+ '0';
3110 /* Generate digits after the decimal point. */
3111 for( k
=0; k
<=ndigs
; k
++ )
3113 /* multiply current number by 10, without normalizing */
3119 eiremain( t
, y
, ldp
);
3120 *s
++ = (char )equot
[NI
-1] + '0';
3122 digit
= equot
[NI
-1];
3125 /* round off the ASCII string */
3128 /* Test for critical rounding case in ASCII output. */
3132 if( ecmp(t
,ezero
) != 0 )
3133 goto roun
; /* round to nearest */
3134 if( (*(s
-1) & 1) == 0 )
3135 goto doexp
; /* round to even */
3137 /* Round up and propagate carry-outs */
3141 /* Carry out to most significant digit? */
3144 /* This will print like "1E-6". */
3155 /* Most significant digit carries to 10? */
3163 /* Round up and carry out from less significant digits */
3175 sprintf( ss
, "e+%02d", expon
);
3177 sprintf( ss
, "e-%02d", -expon
);
3179 sprintf( ss
, "E%d", expon
);
3182 ldp
->rndprc
= rndsav
;
3183 ldp
->outexpon
= expon
;
3191 ; ASCTOQ.MAC LATEST REV: 11 JAN 84
3194 ; Convert ASCII string to quadruple precision floating point
3196 ; Numeric input is free field decimal number
3197 ; with max of 15 digits with or without
3198 ; decimal point entered as ASCII from teletype.
3199 ; Entering E after the number followed by a second
3200 ; number causes the second number to be interpreted
3201 ; as a power of 10 to be multiplied by the first number
3202 ; (i.e., "scientific" notation).
3205 ; asctoq( string, q );
3208 void _simdstrtold (char *s
, char **se
, LONG_DOUBLE_UNION
*x
)
3211 LDPARMS
*ldp
= &rnd
;
3217 lenldstr
= asctoeg( s
, (unsigned short *)x
, SIMD_LDBL_MANT_DIG
, ldp
);
3222 #define REASONABLE_LEN 200
3225 asctoeg(char *ss
, short unsigned int *y
, int oprec
, LDPARMS
*ldp
)
3227 unsigned short yy
[NI
], xt
[NI
], tt
[NI
];
3228 int esign
, decflg
, sgnflg
, nexp
, exp
, prec
, lost
;
3229 int k
, trail
, c
, rndsav
;
3231 unsigned short nsign
, *p
;
3232 char *sp
, *s
, *lstr
;
3235 char tmpstr
[REASONABLE_LEN
];
3237 /* Copy the input string. */
3238 c
= strlen (ss
) + 2;
3239 if (c
<= REASONABLE_LEN
)
3243 lstr
= (char *) calloc (c
, 1);
3248 while( *s
== ' ' ) /* skip leading spaces */
3254 for( k
=0; k
<c
; k
++ )
3256 if( (*sp
++ = *s
++) == '\0' )
3262 rndsav
= ldp
->rndprc
;
3263 ldp
->rndprc
= NBITS
; /* Set to full precision */
3276 if( (k
>= 0) && (k
<= 9) )
3278 /* Ignore leading zeros */
3279 if( (prec
== 0) && (decflg
== 0) && (k
== 0) )
3281 /* Identify and strip trailing zeros after the decimal point. */
3282 if( (trail
== 0) && (decflg
!= 0) )
3285 while( (*sp
>= '0') && (*sp
<= '9') )
3287 /* Check for syntax error */
3289 if( (c
!= 'e') && (c
!= 'E') && (c
!= '\0')
3290 && (c
!= '\n') && (c
!= '\r') && (c
!= ' ')
3300 /* If enough digits were given to more than fill up the yy register,
3301 * continuing until overflow into the high guard word yy[2]
3302 * guarantees that there will be a roundoff bit at the top
3303 * of the low guard word after normalization.
3308 nexp
+= 1; /* count digits after decimal point */
3309 eshup1( yy
); /* multiply current number by 10 */
3315 xt
[NI
-2] = (unsigned short )k
;
3320 /* Mark any lost non-zero digit. */
3322 /* Count lost digits before the decimal point. */
3337 case '.': /* decimal point */
3367 mtherr( "asctoe", DOMAIN
);
3376 /* Exponent interpretation */
3382 /* check for + or - */
3390 while( (*s
>= '0') && (*s
<= '9') )
3408 yy
[E
] = 0x7fff; /* infinity */
3420 /* Pad trailing zeros to minimize power of 10, per IEEE spec. */
3421 while( (nexp
> 0) && (yy
[2] == 0) )
3433 if( (k
= enormlz(yy
)) > NBITS
)
3438 lexp
= (EXONE
- 1 + NBITS
) - k
;
3439 emdnorm( yy
, lost
, 0, lexp
, 64, ldp
);
3440 /* convert to external format */
3443 /* Multiply by 10**nexp. If precision is 64 bits,
3444 * the maximum relative error incurred in forming 10**n
3445 * for 0 <= n <= 324 is 8.2e-20, at 10**180.
3446 * For 0 <= n <= 999, the peak relative error is 1.4e-19 at 10**947.
3447 * For 0 >= n >= -999, it is -1.55e-19 at 10**-435.
3461 { /* Punt. Can't handle this without 2 divides. */
3462 emovi( etens
[0], tt
);
3464 k
= edivm( tt
, yy
, ldp
);
3469 p
= &etens
[NTEN
][0];
3475 emul( p
, xt
, xt
, ldp
);
3479 while( exp
<= MAXP
);
3485 k
= edivm( tt
, yy
, ldp
);
3491 k
= emulm( tt
, yy
, ldp
);
3497 /* Round and convert directly to the destination type */
3499 lexp
-= EXONE
- 0x3ff;
3500 else if( oprec
== 24 )
3501 lexp
-= EXONE
- 0177;
3503 else if( oprec
== 56 )
3504 lexp
-= EXONE
- 0201;
3506 ldp
->rndprc
= oprec
;
3507 emdnorm( yy
, k
, 0, lexp
, 64, ldp
);
3511 ldp
->rndprc
= rndsav
;
3517 todec( yy
, y
); /* see etodec.c */
3520 #if SIMD_LDBL_MANT_DIG == 53
3524 #elif SIMD_LDBL_MANT_DIG == 24
3528 #elif SIMD_LDBL_MANT_DIG == 64
3532 #elif SIMD_LDBL_MANT_DIG == 113
3538 emovo( yy
, y
, ldp
);
3542 lenldstr
+= s
- lstr
;
3550 /* y = largest integer not greater than x
3551 * (truncated toward minus infinity)
3553 * unsigned short x[NE], y[NE]
3556 * efloor( x, y, ldp );
3558 static unsigned short bmask
[] = {
3578 static void efloor(short unsigned int *x
, short unsigned int *y
, LDPARMS
*ldp
)
3580 register unsigned short *p
;
3582 unsigned short f
[NE
];
3584 emov( x
, f
); /* leave in external format */
3585 expon
= (int )f
[NE
-1];
3586 e
= (expon
& 0x7fff) - (EXONE
- 1);
3592 /* number of bits to clear out */
3604 /* clear the remaining bits */
3606 /* truncate negatives toward minus infinity */
3609 if( (unsigned short )expon
& (unsigned short )0x8000 )
3611 for( i
=0; i
<NE
-1; i
++ )
3615 esub( eone
, y
, y
, ldp
);
3624 static void eiremain(short unsigned int *den
, short unsigned int *num
, LDPARMS
*ldp
)
3628 unsigned short *equot
= ldp
->equot
;
3631 ld
-= enormlz( den
);
3633 ln
-= enormlz( num
);
3637 if( ecmpm(den
,num
) <= 0 )
3651 emdnorm( num
, 0, 0, ln
, 0, ldp
);
3657 static unsigned short nan113
[8] = {
3658 0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
3659 static unsigned short nan64
[6] = {0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
3660 static unsigned short nan53
[4] = {0x7fff, 0xffff, 0xffff, 0xffff};
3661 static unsigned short nan24
[2] = {0x7fff, 0xffff};
3663 static unsigned short nan113
[8] = {0, 0, 0, 0, 0, 0, 0x8000, 0x7fff};
3664 static unsigned short nan64
[6] = {0, 0, 0, 0, 0xc000, 0x7fff};
3665 static unsigned short nan53
[4] = {0, 0, 0, 0x7ff8};
3666 static unsigned short nan24
[2] = {0, 0x7fc0};
3670 static void enan (short unsigned int *nan
, int size
)
3699 for( i
=0; i
<NE
-2; i
++ )
3710 for( i
=4; i
<NI
; i
++ )
3715 mtherr( "enan", DOMAIN
);
3718 for (i
=0; i
< n
; i
++)
3722 #endif /* __SPE__ */