1 /* Copyright © 2018, Keith Packard
2    All rights reserved.
3 
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions are met:
6 
7    * Redistributions of source code must retain the above copyright
8      notice, this list of conditions and the following disclaimer.
9    * Redistributions in binary form must reproduce the above copyright
10      notice, this list of conditions and the following disclaimer in
11      the documentation and/or other materials provided with the
12      distribution.
13    * Neither the name of the copyright holders nor the names of
14      contributors may be used to endorse or promote products derived
15      from this software without specific prior written permission.
16 
17   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27   POSSIBILITY OF SUCH DAMAGE. */
28 
29 #ifndef	_DTOA_H_
30 #define	_DTOA_H_
31 
32 #include "stdio_private.h"
33 #include "../../libm/common/math_config.h"
34 
35 #define	DTOA_MINUS	1
36 #define	DTOA_ZERO	2
37 #define	DTOA_INF	4
38 #define	DTOA_NAN	8
39 
40 #if __LDBL_MANT_DIG__ == 113
41 #define LDTOA_MAX_DIG    34
42 #elif __LDBL_MANT_DIG__ == 106
43 #define LDTOA_MAX_DIG    32
44 #elif __LDBL_MANT_DIG__ == 64
45 #define LDTOA_MAX_DIG    20
46 #endif
47 
48 #define DTOA_MAX_DIG            17
49 #define DTOA_MAX_10_EXP         308
50 #define DTOA_MIN_10_EXP         (-307)
51 #define DTOA_SCALE_UP_NUM       9
52 #define DTOA_ROUND_NUM          (DTOA_MAX_DIG + 1)
53 #define DTOA_MAX_EXP            1024
54 
55 #define FTOA_MAX_10_EXP         38
56 #define FTOA_MIN_10_EXP         (-37)
57 #define FTOA_MAX_DIG	        9
58 #define FTOA_SCALE_UP_NUM       6
59 #define FTOA_ROUND_NUM          (FTOA_MAX_DIG + 1)
60 
61 #ifdef _NEED_IO_LONG_DOUBLE
62 # if __SIZEOF_LONG_DOUBLE__ == 4
63 #  define _NEED_IO_FLOAT32
64 #  define LONG_FLOAT_MAX_DIG    FTOA_MAX_DIG
65 #  define __lfloat_d_engine     __ftoa_engine
66 #  define __lfloat_x_engine     __ftox_engine
67 # elif __SIZEOF_LONG_DOUBLE__ == 8
68 #  define _NEED_IO_FLOAT64
69 #  define LONG_FLOAT_MAX_DIG    DTOA_MAX_DIG
70 #  define __lfloat_d_engine     __dtoa_engine
71 #  define __lfloat_x_engine     __dtox_engine
72 # elif __SIZEOF_LONG_DOUBLE__ > 8
73 #  define _NEED_IO_FLOAT_LARGE
74 #  define LONG_FLOAT_MAX_DIG    LDTOA_MAX_DIG
75 #  define __lfloat_d_engine     __ldtoa_engine
76 #  define __lfloat_x_engine     __ldtox_engine
77 # endif
78 #endif
79 
80 #ifdef _NEED_IO_DOUBLE
81 # if __SIZEOF_DOUBLE__ == 4
82 #  define _NEED_IO_FLOAT32
83 #  define FLOAT_MAX_DIG         FTOA_MAX_DIG
84 #  define __float_d_engine      __ftoa_engine
85 #  define __float_x_engine      __ftox_engine
86 # elif __SIZEOF_DOUBLE__ == 8
87 #  define _NEED_IO_FLOAT64
88 #  define FLOAT_MAX_DIG         DTOA_MAX_DIG
89 #  define __float_d_engine      __dtoa_engine
90 #  define __float_x_engine      __dtox_engine
91 # endif
92 # define PRINTF_FLOAT_ARG(ap)   (va_arg(ap, double))
93 #endif
94 
95 #ifdef _NEED_IO_FLOAT
96 # define _NEED_IO_FLOAT32
97 # define PRINTF_FLOAT_ARG(ap) (asfloat(va_arg(ap, uint32_t)))
98 # define FLOAT_MAX_DIG   FTOA_MAX_DIG
99 # define __float_d_engine __ftoa_engine
100 # define __float_x_engine __ftox_engine
101 #endif
102 
103 #ifdef _NEED_IO_FLOAT_LARGE
104 #define DTOA_DIGITS     LDTOA_MAX_DIG
105 #elif defined(_NEED_IO_FLOAT64)
106 #define DTOA_DIGITS     DTOA_MAX_DIG
107 #elif defined(_NEED_IO_FLOAT32)
108 #define DTOA_DIGITS     FTOA_MAX_DIG
109 #else
110 #error No float requirement set
111 #endif
112 
113 struct dtoa {
114     int32_t     exp;
115     uint8_t     flags;
116     char        digits[DTOA_DIGITS];
117 };
118 
119 #ifdef _NEED_IO_FLOAT_LARGE
120 int
121 __ldtoa_engine(long double x, struct dtoa *dtoa, int max_digits, bool fmode, int max_decimals);
122 
123 int
124 __ldtox_engine(long double x, struct dtoa *dtoa, int prec, unsigned char case_convert);
125 
126 long double
127 __atold_engine(_u128 m10, int e10);
128 #endif
129 
130 #ifdef _NEED_IO_FLOAT64
131 int
132 __dtoa_engine(FLOAT64 x, struct dtoa *dtoa, int max_digits, bool fmode, int max_decimals);
133 
134 int
135 __dtox_engine(FLOAT64 x, struct dtoa *dtoa, int prec, unsigned char case_convert);
136 
137 FLOAT64
138 __atod_engine(uint64_t m10, int e10);
139 #endif
140 
141 #ifdef _NEED_IO_FLOAT32
142 int __ftoa_engine (float val, struct dtoa *ftoa, int max_digits, bool fmode, int max_decimals);
143 
144 int
145 __ftox_engine(float x, struct dtoa *dtoa, int prec, unsigned char case_convert);
146 
147 float
148 __atof_engine(uint32_t m10, int e10);
149 #endif
150 
151 #endif	/* !_DTOA_H_ */
152