g_xfmt.c revision 187808
1238104Sdes/****************************************************************
2238104Sdes
3238104SdesThe author of this software is David M. Gay.
4238104Sdes
5238104SdesCopyright (C) 1998 by Lucent Technologies
6238104SdesAll Rights Reserved
7238104Sdes
8238104SdesPermission to use, copy, modify, and distribute this software and
9238104Sdesits documentation for any purpose and without fee is hereby
10238104Sdesgranted, provided that the above copyright notice appear in all
11238104Sdescopies and that both that the copyright notice and this
12238104Sdespermission notice and warranty disclaimer appear in supporting
13238104Sdesdocumentation, and that the name of Lucent or any of its entities
14238104Sdesnot be used in advertising or publicity pertaining to
15238104Sdesdistribution of the software without specific, written prior
16238104Sdespermission.
17238104Sdes
18238104SdesLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19238104SdesINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20238104SdesIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21238104SdesSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22238104SdesWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23269257SdesIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24238104SdesARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25238104SdesTHIS SOFTWARE.
26238104Sdes
27238104Sdes****************************************************************/
28238104Sdes
29238104Sdes/* Please send bug reports to David M. Gay (dmg at acm dot org,
30238104Sdes * with " at " changed at "@" and " dot " changed to ".").	*/
31238104Sdes
32238104Sdes#include "gdtoaimp.h"
33238104Sdes
34238104Sdes#undef _0
35238104Sdes#undef _1
36238104Sdes
37238104Sdes/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
38238104Sdes
39238104Sdes#ifdef IEEE_MC68k
40238104Sdes#define _0 0
41238104Sdes#define _1 1
42238104Sdes#define _2 2
43238104Sdes#define _3 3
44238104Sdes#define _4 4
45238104Sdes#endif
46238104Sdes#ifdef IEEE_8087
47238104Sdes#define _0 4
48238104Sdes#define _1 3
49238104Sdes#define _2 2
50238104Sdes#define _3 1
51238104Sdes#define _4 0
52238104Sdes#endif
53238104Sdes
54238104Sdes char*
55238104Sdes#ifdef KR_headers
56238104Sdesg_xfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; size_t bufsize;
57238104Sdes#else
58238104Sdesg_xfmt(char *buf, void *V, int ndig, size_t bufsize)
59238104Sdes#endif
60238104Sdes{
61238104Sdes	static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
62238104Sdes	char *b, *s, *se;
63238104Sdes	ULong bits[2], sign;
64238104Sdes	UShort *L;
65238104Sdes	int decpt, ex, i, mode;
66238104Sdes#ifdef Honor_FLT_ROUNDS
67238104Sdes#include "gdtoa_fltrnds.h"
68238104Sdes#else
69238104Sdes#define fpi &fpi0
70238104Sdes#endif
71238104Sdes
72238104Sdes	if (ndig < 0)
73238104Sdes		ndig = 0;
74238104Sdes	if (bufsize < ndig + 10)
75238104Sdes		return 0;
76238104Sdes
77238104Sdes	L = (UShort *)V;
78238104Sdes	sign = L[_0] & 0x8000;
79238104Sdes	bits[1] = (L[_1] << 16) | L[_2];
80238104Sdes	bits[0] = (L[_3] << 16) | L[_4];
81238104Sdes	if ( (ex = L[_0] & 0x7fff) !=0) {
82238104Sdes		if (ex == 0x7fff) {
83238104Sdes			/* Infinity or NaN */
84238104Sdes			if (bits[0] | bits[1])
85238104Sdes				b = strcp(buf, "NaN");
86238104Sdes			else {
87238104Sdes				b = buf;
88238104Sdes				if (sign)
89238104Sdes					*b++ = '-';
90238104Sdes				b = strcp(b, "Infinity");
91238104Sdes				}
92238104Sdes			return b;
93238104Sdes			}
94238104Sdes		i = STRTOG_Normal;
95238104Sdes		}
96238104Sdes	else if (bits[0] | bits[1]) {
97238104Sdes		i = STRTOG_Denormal;
98238104Sdes		ex = 1;
99238104Sdes		}
100238104Sdes	else {
101238104Sdes		b = buf;
102238104Sdes#ifndef IGNORE_ZERO_SIGN
103238104Sdes		if (sign)
104238104Sdes			*b++ = '-';
105238104Sdes#endif
106238104Sdes		*b++ = '0';
107238104Sdes		*b = 0;
108238104Sdes		return b;
109238104Sdes		}
110238104Sdes	ex -= 0x3fff + 63;
111238104Sdes	mode = 2;
112238104Sdes	if (ndig <= 0) {
113238104Sdes		if (bufsize < 32)
114238104Sdes			return 0;
115238104Sdes		mode = 0;
116238104Sdes		}
117238104Sdes	s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
118238104Sdes	return g__fmt(buf, s, se, decpt, sign, bufsize);
119238104Sdes	}
120238104Sdes