]> git.saurik.com Git - apple/libc.git/blame - gdtoa/_ldtoa-fbsd.c
Libc-594.1.4.tar.gz
[apple/libc.git] / gdtoa / _ldtoa-fbsd.c
CommitLineData
224c7076
A
1/*-
2 * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: src/lib/libc/gdtoa/_ldtoa.c,v 1.2 2004/01/18 07:53:49 das Exp $");
29
30#include <float.h>
31#include <inttypes.h>
32#include <limits.h>
33#include <math.h>
34#include <stdlib.h>
35#include "fpmath.h"
36#include "gdtoaimp.h"
37
38/*
39 * ldtoa() is a wrapper for gdtoa() that makes it smell like dtoa(),
40 * except that the floating point argument is passed by reference.
41 * When dtoa() is passed a NaN or infinity, it sets expt to 9999.
42 * However, a long double could have a valid exponent of 9999, so we
43 * use INT_MAX in ldtoa() instead.
44 */
45char *
46__ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign,
47 char **rve)
48{
49 static FPI fpi0 = {
50 LDBL_MANT_DIG, /* nbits */
51 LDBL_MIN_EXP - LDBL_MANT_DIG, /* emin */
52 LDBL_MAX_EXP - LDBL_MANT_DIG, /* emax */
53 FPI_Round_near, /* rounding */
54#ifdef Sudden_Underflow /* unused, but correct anyway */
55 1
56#else
57 0
58#endif
59 };
60 int be, kind;
61 char *ret;
62 union IEEEl2bits u;
63 uint32_t bits[(LDBL_MANT_DIG + 31) / 32];
64 FPI *fpi = &fpi0, fpi1;
65#ifdef Honor_FLT_ROUNDS
66 int rounding = Flt_Rounds;
67#endif
224c7076 68 int type;
224c7076
A
69
70 u.e = *ld;
71#if defined(__ppc__) || defined(__ppc64__)
72 /*
73 * Subnormal head-tail doubles don't seem to be converted correctly
74 * by gdtoa. So we multiply by 10^32 to make them normal then
75 * subtract 32 from the exponent later.
76 */
77 if ((type = __fpclassify(u.e)) == FP_NORMAL && __fpclassifyd(u.d[1]) == FP_SUBNORMAL)
78 type = FP_SUBNORMAL;
79 if (type == FP_SUBNORMAL)
80 u.e *= 1.0e32L;
34e8f829
A
81#else /* !defined(__ppc__) && !defined(__ppc64__) */
82 type = fpclassify(u.e);
224c7076
A
83#endif /* defined(__ppc__) || defined(__ppc64__) */
84 *sign = u.bits.sign;
85 be = u.bits.exp - (LDBL_MAX_EXP - 1) - (LDBL_MANT_DIG - 1);
34e8f829
A
86#if defined(__ppc__) || defined(__ppc64__)
87 be -= LDBL_TO_ARRAY32(u, bits);
88#else /* !defined(__ppc__) && !defined(__ppc64__) */
224c7076 89 LDBL_TO_ARRAY32(u, bits);
34e8f829 90#endif /* defined(__ppc__) || defined(__ppc64__) */
224c7076 91
224c7076 92 switch (type) {
34e8f829 93#if defined(__ppc__) || defined(__ppc64__)
224c7076 94 case FP_SUBNORMAL:
224c7076
A
95#endif /* defined(__ppc__) || defined(__ppc64__) */
96 case FP_NORMAL:
97 case FP_SUPERNORMAL:
98 kind = STRTOG_Normal;
99/* For ppc/ppc64 and head-tail long double, the implicit bit is already there */
100#if !defined(__ppc__) && !defined(__ppc64__)
101#ifdef LDBL_IMPLICIT_NBIT
102 bits[LDBL_MANT_DIG / 32] |= 1 << ((LDBL_MANT_DIG - 1) % 32);
103#endif /* LDBL_IMPLICIT_NBIT */
104#endif /* !defined(__ppc__) && !defined(__ppc64__) */
105 break;
106 case FP_ZERO:
107 kind = STRTOG_Zero;
108 break;
109#if !defined(__ppc__) && !defined(__ppc64__)
110 case FP_SUBNORMAL:
111 kind = STRTOG_Denormal;
112 be++;
113 break;
114#endif /* !defined(__ppc__) && !defined(__ppc64__) */
115 case FP_INFINITE:
116 kind = STRTOG_Infinite;
117 break;
118 case FP_NAN:
119 kind = STRTOG_NaN;
120 break;
121 default:
34e8f829 122 LIBC_ABORT("fpclassify returned %d", type);
224c7076
A
123 }
124
125#ifdef Honor_FLT_ROUNDS
126 if (rounding != fpi0.rounding) {
127 fpi1 = fpi0; /* for thread safety */
128 fpi1.rounding = rounding;
129 fpi = &fpi1;
130 }
131#endif /* Honor_FLT_ROUNDS */
132 ret = gdtoa(fpi, be, (ULong *)bits, &kind, mode, ndigits, decpt, rve);
133 if (*decpt == -32768)
134 *decpt = INT_MAX;
135#if defined(__ppc__) || defined(__ppc64__)
136 else if (type == FP_SUBNORMAL)
137 *decpt -= 32;
138#endif /* defined(__ppc__) || defined(__ppc64__) */
139 return ret;
140}