1*627f7eb2Smrg /* Print floating point number in hexadecimal notation according to ISO C99.
2*627f7eb2Smrg Copyright (C) 1997-2012 Free Software Foundation, Inc.
3*627f7eb2Smrg This file is part of the GNU C Library.
4*627f7eb2Smrg Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
5*627f7eb2Smrg
6*627f7eb2Smrg The GNU C Library is free software; you can redistribute it and/or
7*627f7eb2Smrg modify it under the terms of the GNU Lesser General Public
8*627f7eb2Smrg License as published by the Free Software Foundation; either
9*627f7eb2Smrg version 2.1 of the License, or (at your option) any later version.
10*627f7eb2Smrg
11*627f7eb2Smrg The GNU C Library is distributed in the hope that it will be useful,
12*627f7eb2Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
13*627f7eb2Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14*627f7eb2Smrg Lesser General Public License for more details.
15*627f7eb2Smrg
16*627f7eb2Smrg You should have received a copy of the GNU Lesser General Public
17*627f7eb2Smrg License along with the GNU C Library; if not, see
18*627f7eb2Smrg <http://www.gnu.org/licenses/>. */
19*627f7eb2Smrg
20*627f7eb2Smrg #include <config.h>
21*627f7eb2Smrg #include <math.h>
22*627f7eb2Smrg #include <stdlib.h>
23*627f7eb2Smrg #include <stdio.h>
24*627f7eb2Smrg #include <string.h>
25*627f7eb2Smrg #include <stdbool.h>
26*627f7eb2Smrg #define NDEBUG
27*627f7eb2Smrg #include <assert.h>
28*627f7eb2Smrg #include "quadmath-rounding-mode.h"
29*627f7eb2Smrg #include "quadmath-printf.h"
30*627f7eb2Smrg #include "_itoa.h"
31*627f7eb2Smrg #include "_itowa.h"
32*627f7eb2Smrg
33*627f7eb2Smrg
34*627f7eb2Smrg /* Macros for doing the actual output. */
35*627f7eb2Smrg
36*627f7eb2Smrg #define outchar(ch) \
37*627f7eb2Smrg do \
38*627f7eb2Smrg { \
39*627f7eb2Smrg register const int outc = (ch); \
40*627f7eb2Smrg if (PUTC (outc, fp) == EOF) \
41*627f7eb2Smrg return -1; \
42*627f7eb2Smrg ++done; \
43*627f7eb2Smrg } while (0)
44*627f7eb2Smrg
45*627f7eb2Smrg #define PRINT(ptr, wptr, len) \
46*627f7eb2Smrg do \
47*627f7eb2Smrg { \
48*627f7eb2Smrg register size_t outlen = (len); \
49*627f7eb2Smrg if (wide) \
50*627f7eb2Smrg while (outlen-- > 0) \
51*627f7eb2Smrg outchar (*wptr++); \
52*627f7eb2Smrg else \
53*627f7eb2Smrg while (outlen-- > 0) \
54*627f7eb2Smrg outchar (*ptr++); \
55*627f7eb2Smrg } while (0)
56*627f7eb2Smrg
57*627f7eb2Smrg #define PADN(ch, len) \
58*627f7eb2Smrg do \
59*627f7eb2Smrg { \
60*627f7eb2Smrg if (PAD (fp, ch, len) != len) \
61*627f7eb2Smrg return -1; \
62*627f7eb2Smrg done += len; \
63*627f7eb2Smrg } \
64*627f7eb2Smrg while (0)
65*627f7eb2Smrg
66*627f7eb2Smrg
67*627f7eb2Smrg
68*627f7eb2Smrg int
__quadmath_printf_fphex(struct __quadmath_printf_file * fp,const struct printf_info * info,const void * const * args)69*627f7eb2Smrg __quadmath_printf_fphex (struct __quadmath_printf_file *fp,
70*627f7eb2Smrg const struct printf_info *info,
71*627f7eb2Smrg const void *const *args)
72*627f7eb2Smrg {
73*627f7eb2Smrg /* The floating-point value to output. */
74*627f7eb2Smrg ieee854_float128 fpnum;
75*627f7eb2Smrg
76*627f7eb2Smrg /* Locale-dependent representation of decimal point. */
77*627f7eb2Smrg const char *decimal;
78*627f7eb2Smrg wchar_t decimalwc;
79*627f7eb2Smrg
80*627f7eb2Smrg /* "NaN" or "Inf" for the special cases. */
81*627f7eb2Smrg const char *special = NULL;
82*627f7eb2Smrg const wchar_t *wspecial = NULL;
83*627f7eb2Smrg
84*627f7eb2Smrg /* Buffer for the generated number string for the mantissa. The
85*627f7eb2Smrg maximal size for the mantissa is 128 bits. */
86*627f7eb2Smrg char numbuf[32];
87*627f7eb2Smrg char *numstr;
88*627f7eb2Smrg char *numend;
89*627f7eb2Smrg wchar_t wnumbuf[32];
90*627f7eb2Smrg wchar_t *wnumstr;
91*627f7eb2Smrg wchar_t *wnumend;
92*627f7eb2Smrg int negative;
93*627f7eb2Smrg
94*627f7eb2Smrg /* The maximal exponent of two in decimal notation has 5 digits. */
95*627f7eb2Smrg char expbuf[5];
96*627f7eb2Smrg char *expstr;
97*627f7eb2Smrg wchar_t wexpbuf[5];
98*627f7eb2Smrg wchar_t *wexpstr;
99*627f7eb2Smrg int expnegative;
100*627f7eb2Smrg int exponent;
101*627f7eb2Smrg
102*627f7eb2Smrg /* Non-zero is mantissa is zero. */
103*627f7eb2Smrg int zero_mantissa;
104*627f7eb2Smrg
105*627f7eb2Smrg /* The leading digit before the decimal point. */
106*627f7eb2Smrg char leading;
107*627f7eb2Smrg
108*627f7eb2Smrg /* Precision. */
109*627f7eb2Smrg int precision = info->prec;
110*627f7eb2Smrg
111*627f7eb2Smrg /* Width. */
112*627f7eb2Smrg int width = info->width;
113*627f7eb2Smrg
114*627f7eb2Smrg /* Number of characters written. */
115*627f7eb2Smrg int done = 0;
116*627f7eb2Smrg
117*627f7eb2Smrg /* Nonzero if this is output on a wide character stream. */
118*627f7eb2Smrg int wide = info->wide;
119*627f7eb2Smrg
120*627f7eb2Smrg bool do_round_away;
121*627f7eb2Smrg
122*627f7eb2Smrg /* Figure out the decimal point character. */
123*627f7eb2Smrg #ifdef USE_NL_LANGINFO
124*627f7eb2Smrg if (info->extra == 0)
125*627f7eb2Smrg decimal = nl_langinfo (DECIMAL_POINT);
126*627f7eb2Smrg else
127*627f7eb2Smrg {
128*627f7eb2Smrg decimal = nl_langinfo (MON_DECIMAL_POINT);
129*627f7eb2Smrg if (*decimal == '\0')
130*627f7eb2Smrg decimal = nl_langinfo (DECIMAL_POINT);
131*627f7eb2Smrg }
132*627f7eb2Smrg /* The decimal point character must never be zero. */
133*627f7eb2Smrg assert (*decimal != '\0');
134*627f7eb2Smrg #elif defined USE_LOCALECONV
135*627f7eb2Smrg const struct lconv *lc = localeconv ();
136*627f7eb2Smrg if (info->extra == 0)
137*627f7eb2Smrg decimal = lc->decimal_point;
138*627f7eb2Smrg else
139*627f7eb2Smrg {
140*627f7eb2Smrg decimal = lc->mon_decimal_point;
141*627f7eb2Smrg if (decimal == NULL || *decimal == '\0')
142*627f7eb2Smrg decimal = lc->decimal_point;
143*627f7eb2Smrg }
144*627f7eb2Smrg if (decimal == NULL || *decimal == '\0')
145*627f7eb2Smrg decimal = ".";
146*627f7eb2Smrg #else
147*627f7eb2Smrg decimal = ".";
148*627f7eb2Smrg #endif
149*627f7eb2Smrg #ifdef USE_NL_LANGINFO_WC
150*627f7eb2Smrg if (info->extra == 0)
151*627f7eb2Smrg decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
152*627f7eb2Smrg else
153*627f7eb2Smrg {
154*627f7eb2Smrg decimalwc = nl_langinfo_wc (_NL_MONETARY_DECIMAL_POINT_WC);
155*627f7eb2Smrg if (decimalwc == L_('\0'))
156*627f7eb2Smrg decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
157*627f7eb2Smrg }
158*627f7eb2Smrg /* The decimal point character must never be zero. */
159*627f7eb2Smrg assert (decimalwc != L_('\0'));
160*627f7eb2Smrg #else
161*627f7eb2Smrg decimalwc = L_('.');
162*627f7eb2Smrg #endif
163*627f7eb2Smrg
164*627f7eb2Smrg /* Fetch the argument value. */
165*627f7eb2Smrg {
166*627f7eb2Smrg fpnum.value = **(const __float128 **) args[0];
167*627f7eb2Smrg
168*627f7eb2Smrg /* Check for special values: not a number or infinity. */
169*627f7eb2Smrg if (isnanq (fpnum.value))
170*627f7eb2Smrg {
171*627f7eb2Smrg negative = fpnum.ieee.negative != 0;
172*627f7eb2Smrg if (isupper (info->spec))
173*627f7eb2Smrg {
174*627f7eb2Smrg special = "NAN";
175*627f7eb2Smrg wspecial = L_("NAN");
176*627f7eb2Smrg }
177*627f7eb2Smrg else
178*627f7eb2Smrg {
179*627f7eb2Smrg special = "nan";
180*627f7eb2Smrg wspecial = L_("nan");
181*627f7eb2Smrg }
182*627f7eb2Smrg }
183*627f7eb2Smrg else
184*627f7eb2Smrg {
185*627f7eb2Smrg if (isinfq (fpnum.value))
186*627f7eb2Smrg {
187*627f7eb2Smrg if (isupper (info->spec))
188*627f7eb2Smrg {
189*627f7eb2Smrg special = "INF";
190*627f7eb2Smrg wspecial = L_("INF");
191*627f7eb2Smrg }
192*627f7eb2Smrg else
193*627f7eb2Smrg {
194*627f7eb2Smrg special = "inf";
195*627f7eb2Smrg wspecial = L_("inf");
196*627f7eb2Smrg }
197*627f7eb2Smrg }
198*627f7eb2Smrg
199*627f7eb2Smrg negative = signbitq (fpnum.value);
200*627f7eb2Smrg }
201*627f7eb2Smrg }
202*627f7eb2Smrg
203*627f7eb2Smrg if (special)
204*627f7eb2Smrg {
205*627f7eb2Smrg int width = info->width;
206*627f7eb2Smrg
207*627f7eb2Smrg if (negative || info->showsign || info->space)
208*627f7eb2Smrg --width;
209*627f7eb2Smrg width -= 3;
210*627f7eb2Smrg
211*627f7eb2Smrg if (!info->left && width > 0)
212*627f7eb2Smrg PADN (' ', width);
213*627f7eb2Smrg
214*627f7eb2Smrg if (negative)
215*627f7eb2Smrg outchar ('-');
216*627f7eb2Smrg else if (info->showsign)
217*627f7eb2Smrg outchar ('+');
218*627f7eb2Smrg else if (info->space)
219*627f7eb2Smrg outchar (' ');
220*627f7eb2Smrg
221*627f7eb2Smrg PRINT (special, wspecial, 3);
222*627f7eb2Smrg
223*627f7eb2Smrg if (info->left && width > 0)
224*627f7eb2Smrg PADN (' ', width);
225*627f7eb2Smrg
226*627f7eb2Smrg return done;
227*627f7eb2Smrg }
228*627f7eb2Smrg
229*627f7eb2Smrg {
230*627f7eb2Smrg /* We have 112 bits of mantissa plus one implicit digit. Since
231*627f7eb2Smrg 112 bits are representable without rest using hexadecimal
232*627f7eb2Smrg digits we use only the implicit digits for the number before
233*627f7eb2Smrg the decimal point. */
234*627f7eb2Smrg uint64_t num0, num1;
235*627f7eb2Smrg
236*627f7eb2Smrg assert (sizeof (long double) == 16);
237*627f7eb2Smrg
238*627f7eb2Smrg num0 = (((unsigned long long int) fpnum.ieee.mantissa0) << 32
239*627f7eb2Smrg | fpnum.ieee.mantissa1);
240*627f7eb2Smrg num1 = (((unsigned long long int) fpnum.ieee.mantissa2) << 32
241*627f7eb2Smrg | fpnum.ieee.mantissa3);
242*627f7eb2Smrg
243*627f7eb2Smrg zero_mantissa = (num0|num1) == 0;
244*627f7eb2Smrg
245*627f7eb2Smrg if (sizeof (unsigned long int) > 6)
246*627f7eb2Smrg {
247*627f7eb2Smrg numstr = _itoa_word (num1, numbuf + sizeof numbuf, 16,
248*627f7eb2Smrg info->spec == 'A');
249*627f7eb2Smrg wnumstr = _itowa_word (num1,
250*627f7eb2Smrg wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),
251*627f7eb2Smrg 16, info->spec == 'A');
252*627f7eb2Smrg }
253*627f7eb2Smrg else
254*627f7eb2Smrg {
255*627f7eb2Smrg numstr = _itoa (num1, numbuf + sizeof numbuf, 16,
256*627f7eb2Smrg info->spec == 'A');
257*627f7eb2Smrg wnumstr = _itowa (num1,
258*627f7eb2Smrg wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),
259*627f7eb2Smrg 16, info->spec == 'A');
260*627f7eb2Smrg }
261*627f7eb2Smrg
262*627f7eb2Smrg while (numstr > numbuf + (sizeof numbuf - 64 / 4))
263*627f7eb2Smrg {
264*627f7eb2Smrg *--numstr = '0';
265*627f7eb2Smrg *--wnumstr = L_('0');
266*627f7eb2Smrg }
267*627f7eb2Smrg
268*627f7eb2Smrg if (sizeof (unsigned long int) > 6)
269*627f7eb2Smrg {
270*627f7eb2Smrg numstr = _itoa_word (num0, numstr, 16, info->spec == 'A');
271*627f7eb2Smrg wnumstr = _itowa_word (num0, wnumstr, 16, info->spec == 'A');
272*627f7eb2Smrg }
273*627f7eb2Smrg else
274*627f7eb2Smrg {
275*627f7eb2Smrg numstr = _itoa (num0, numstr, 16, info->spec == 'A');
276*627f7eb2Smrg wnumstr = _itowa (num0, wnumstr, 16, info->spec == 'A');
277*627f7eb2Smrg }
278*627f7eb2Smrg
279*627f7eb2Smrg /* Fill with zeroes. */
280*627f7eb2Smrg while (numstr > numbuf + (sizeof numbuf - 112 / 4))
281*627f7eb2Smrg {
282*627f7eb2Smrg *--wnumstr = L_('0');
283*627f7eb2Smrg *--numstr = '0';
284*627f7eb2Smrg }
285*627f7eb2Smrg
286*627f7eb2Smrg leading = fpnum.ieee.exponent == 0 ? '0' : '1';
287*627f7eb2Smrg
288*627f7eb2Smrg exponent = fpnum.ieee.exponent;
289*627f7eb2Smrg
290*627f7eb2Smrg if (exponent == 0)
291*627f7eb2Smrg {
292*627f7eb2Smrg if (zero_mantissa)
293*627f7eb2Smrg expnegative = 0;
294*627f7eb2Smrg else
295*627f7eb2Smrg {
296*627f7eb2Smrg /* This is a denormalized number. */
297*627f7eb2Smrg expnegative = 1;
298*627f7eb2Smrg exponent = IEEE854_FLOAT128_BIAS - 1;
299*627f7eb2Smrg }
300*627f7eb2Smrg }
301*627f7eb2Smrg else if (exponent >= IEEE854_FLOAT128_BIAS)
302*627f7eb2Smrg {
303*627f7eb2Smrg expnegative = 0;
304*627f7eb2Smrg exponent -= IEEE854_FLOAT128_BIAS;
305*627f7eb2Smrg }
306*627f7eb2Smrg else
307*627f7eb2Smrg {
308*627f7eb2Smrg expnegative = 1;
309*627f7eb2Smrg exponent = -(exponent - IEEE854_FLOAT128_BIAS);
310*627f7eb2Smrg }
311*627f7eb2Smrg }
312*627f7eb2Smrg
313*627f7eb2Smrg /* Look for trailing zeroes. */
314*627f7eb2Smrg if (! zero_mantissa)
315*627f7eb2Smrg {
316*627f7eb2Smrg wnumend = &wnumbuf[sizeof wnumbuf / sizeof wnumbuf[0]];
317*627f7eb2Smrg numend = &numbuf[sizeof numbuf / sizeof numbuf[0]];
318*627f7eb2Smrg while (wnumend[-1] == L_('0'))
319*627f7eb2Smrg {
320*627f7eb2Smrg --wnumend;
321*627f7eb2Smrg --numend;
322*627f7eb2Smrg }
323*627f7eb2Smrg
324*627f7eb2Smrg do_round_away = false;
325*627f7eb2Smrg
326*627f7eb2Smrg if (precision != -1 && precision < numend - numstr)
327*627f7eb2Smrg {
328*627f7eb2Smrg char last_digit = precision > 0 ? numstr[precision - 1] : leading;
329*627f7eb2Smrg char next_digit = numstr[precision];
330*627f7eb2Smrg int last_digit_value = (last_digit >= 'A' && last_digit <= 'F'
331*627f7eb2Smrg ? last_digit - 'A' + 10
332*627f7eb2Smrg : (last_digit >= 'a' && last_digit <= 'f'
333*627f7eb2Smrg ? last_digit - 'a' + 10
334*627f7eb2Smrg : last_digit - '0'));
335*627f7eb2Smrg int next_digit_value = (next_digit >= 'A' && next_digit <= 'F'
336*627f7eb2Smrg ? next_digit - 'A' + 10
337*627f7eb2Smrg : (next_digit >= 'a' && next_digit <= 'f'
338*627f7eb2Smrg ? next_digit - 'a' + 10
339*627f7eb2Smrg : next_digit - '0'));
340*627f7eb2Smrg bool more_bits = ((next_digit_value & 7) != 0
341*627f7eb2Smrg || precision + 1 < numend - numstr);
342*627f7eb2Smrg #ifdef HAVE_FENV_H
343*627f7eb2Smrg int rounding_mode = get_rounding_mode ();
344*627f7eb2Smrg do_round_away = round_away (negative, last_digit_value & 1,
345*627f7eb2Smrg next_digit_value >= 8, more_bits,
346*627f7eb2Smrg rounding_mode);
347*627f7eb2Smrg #endif
348*627f7eb2Smrg }
349*627f7eb2Smrg
350*627f7eb2Smrg if (precision == -1)
351*627f7eb2Smrg precision = numend - numstr;
352*627f7eb2Smrg else if (do_round_away)
353*627f7eb2Smrg {
354*627f7eb2Smrg /* Round up. */
355*627f7eb2Smrg int cnt = precision;
356*627f7eb2Smrg while (--cnt >= 0)
357*627f7eb2Smrg {
358*627f7eb2Smrg char ch = numstr[cnt];
359*627f7eb2Smrg /* We assume that the digits and the letters are ordered
360*627f7eb2Smrg like in ASCII. This is true for the rest of GNU, too. */
361*627f7eb2Smrg if (ch == '9')
362*627f7eb2Smrg {
363*627f7eb2Smrg wnumstr[cnt] = (wchar_t) info->spec;
364*627f7eb2Smrg numstr[cnt] = info->spec; /* This is tricky,
365*627f7eb2Smrg think about it! */
366*627f7eb2Smrg break;
367*627f7eb2Smrg }
368*627f7eb2Smrg else if (tolower (ch) < 'f')
369*627f7eb2Smrg {
370*627f7eb2Smrg ++numstr[cnt];
371*627f7eb2Smrg ++wnumstr[cnt];
372*627f7eb2Smrg break;
373*627f7eb2Smrg }
374*627f7eb2Smrg else
375*627f7eb2Smrg {
376*627f7eb2Smrg numstr[cnt] = '0';
377*627f7eb2Smrg wnumstr[cnt] = L_('0');
378*627f7eb2Smrg }
379*627f7eb2Smrg }
380*627f7eb2Smrg if (cnt < 0)
381*627f7eb2Smrg {
382*627f7eb2Smrg /* The mantissa so far was fff...f Now increment the
383*627f7eb2Smrg leading digit. Here it is again possible that we
384*627f7eb2Smrg get an overflow. */
385*627f7eb2Smrg if (leading == '9')
386*627f7eb2Smrg leading = info->spec;
387*627f7eb2Smrg else if (tolower (leading) < 'f')
388*627f7eb2Smrg ++leading;
389*627f7eb2Smrg else
390*627f7eb2Smrg {
391*627f7eb2Smrg leading = '1';
392*627f7eb2Smrg if (expnegative)
393*627f7eb2Smrg {
394*627f7eb2Smrg exponent -= 4;
395*627f7eb2Smrg if (exponent <= 0)
396*627f7eb2Smrg {
397*627f7eb2Smrg exponent = -exponent;
398*627f7eb2Smrg expnegative = 0;
399*627f7eb2Smrg }
400*627f7eb2Smrg }
401*627f7eb2Smrg else
402*627f7eb2Smrg exponent += 4;
403*627f7eb2Smrg }
404*627f7eb2Smrg }
405*627f7eb2Smrg }
406*627f7eb2Smrg }
407*627f7eb2Smrg else
408*627f7eb2Smrg {
409*627f7eb2Smrg if (precision == -1)
410*627f7eb2Smrg precision = 0;
411*627f7eb2Smrg numend = numstr;
412*627f7eb2Smrg wnumend = wnumstr;
413*627f7eb2Smrg }
414*627f7eb2Smrg
415*627f7eb2Smrg /* Now we can compute the exponent string. */
416*627f7eb2Smrg expstr = _itoa_word (exponent, expbuf + sizeof expbuf, 10, 0);
417*627f7eb2Smrg wexpstr = _itowa_word (exponent,
418*627f7eb2Smrg wexpbuf + sizeof wexpbuf / sizeof (wchar_t), 10, 0);
419*627f7eb2Smrg
420*627f7eb2Smrg /* Now we have all information to compute the size. */
421*627f7eb2Smrg width -= ((negative || info->showsign || info->space)
422*627f7eb2Smrg /* Sign. */
423*627f7eb2Smrg + 2 + 1 + 0 + precision + 1 + 1
424*627f7eb2Smrg /* 0x h . hhh P ExpoSign. */
425*627f7eb2Smrg + ((expbuf + sizeof expbuf) - expstr));
426*627f7eb2Smrg /* Exponent. */
427*627f7eb2Smrg
428*627f7eb2Smrg /* Count the decimal point.
429*627f7eb2Smrg A special case when the mantissa or the precision is zero and the `#'
430*627f7eb2Smrg is not given. In this case we must not print the decimal point. */
431*627f7eb2Smrg if (precision > 0 || info->alt)
432*627f7eb2Smrg width -= wide ? 1 : strlen (decimal);
433*627f7eb2Smrg
434*627f7eb2Smrg if (!info->left && info->pad != '0' && width > 0)
435*627f7eb2Smrg PADN (' ', width);
436*627f7eb2Smrg
437*627f7eb2Smrg if (negative)
438*627f7eb2Smrg outchar ('-');
439*627f7eb2Smrg else if (info->showsign)
440*627f7eb2Smrg outchar ('+');
441*627f7eb2Smrg else if (info->space)
442*627f7eb2Smrg outchar (' ');
443*627f7eb2Smrg
444*627f7eb2Smrg outchar ('0');
445*627f7eb2Smrg if ('X' - 'A' == 'x' - 'a')
446*627f7eb2Smrg outchar (info->spec + ('x' - 'a'));
447*627f7eb2Smrg else
448*627f7eb2Smrg outchar (info->spec == 'A' ? 'X' : 'x');
449*627f7eb2Smrg
450*627f7eb2Smrg if (!info->left && info->pad == '0' && width > 0)
451*627f7eb2Smrg PADN ('0', width);
452*627f7eb2Smrg
453*627f7eb2Smrg outchar (leading);
454*627f7eb2Smrg
455*627f7eb2Smrg if (precision > 0 || info->alt)
456*627f7eb2Smrg {
457*627f7eb2Smrg const wchar_t *wtmp = &decimalwc;
458*627f7eb2Smrg PRINT (decimal, wtmp, wide ? 1 : strlen (decimal));
459*627f7eb2Smrg }
460*627f7eb2Smrg
461*627f7eb2Smrg if (precision > 0)
462*627f7eb2Smrg {
463*627f7eb2Smrg ssize_t tofill = precision - (numend - numstr);
464*627f7eb2Smrg PRINT (numstr, wnumstr, MIN (numend - numstr, precision));
465*627f7eb2Smrg if (tofill > 0)
466*627f7eb2Smrg PADN ('0', tofill);
467*627f7eb2Smrg }
468*627f7eb2Smrg
469*627f7eb2Smrg if ('P' - 'A' == 'p' - 'a')
470*627f7eb2Smrg outchar (info->spec + ('p' - 'a'));
471*627f7eb2Smrg else
472*627f7eb2Smrg outchar (info->spec == 'A' ? 'P' : 'p');
473*627f7eb2Smrg
474*627f7eb2Smrg outchar (expnegative ? '-' : '+');
475*627f7eb2Smrg
476*627f7eb2Smrg PRINT (expstr, wexpstr, (expbuf + sizeof expbuf) - expstr);
477*627f7eb2Smrg
478*627f7eb2Smrg if (info->left && info->pad != '0' && width > 0)
479*627f7eb2Smrg PADN (info->pad, width);
480*627f7eb2Smrg
481*627f7eb2Smrg return done;
482*627f7eb2Smrg }
483