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 #define	DTOA_CARRY	16	/* Carry was to most significant position. */
40 
41 #if __LDBL_MANT_DIG__ == 113
42 #define LDTOA_MAX_DIG    34
43 #elif __LDBL_MANT_DIG__ == 106
44 #define LDTOA_MAX_DIG    32
45 #elif __LDBL_MANT_DIG__ == 64
46 #define LDTOA_MAX_DIG    20
47 #endif
48 
49 #define DTOA_MAX_DIG            17
50 #define DTOA_MAX_10_EXP         308
51 #define DTOA_MIN_10_EXP         (-307)
52 #define DTOA_SCALE_UP_NUM       9
53 #define DTOA_ROUND_NUM          (DTOA_MAX_DIG + 1)
54 #define DTOA_MAX_EXP            1024
55 
56 #define FTOA_MAX_10_EXP         38
57 #define FTOA_MIN_10_EXP         (-37)
58 #define FTOA_MAX_DIG	        9
59 #define FTOA_SCALE_UP_NUM       6
60 #define FTOA_ROUND_NUM          (FTOA_MAX_DIG + 1)
61 
62 #ifdef _NEED_IO_LONG_DOUBLE
63 # if __SIZEOF_LONG_DOUBLE__ == 4
64 #  define _NEED_IO_FLOAT32
65 #  define LONG_FLOAT_MAX_DIG    FTOA_MAX_DIG
66 #  define __lfloat_d_engine     __ftoa_engine
67 #  define __lfloat_x_engine     __ftox_engine
68 # elif __SIZEOF_LONG_DOUBLE__ == 8
69 #  define _NEED_IO_FLOAT64
70 #  define LONG_FLOAT_MAX_DIG    DTOA_MAX_DIG
71 #  define __lfloat_d_engine     __dtoa_engine
72 #  define __lfloat_x_engine     __dtox_engine
73 # elif __SIZEOF_LONG_DOUBLE__ > 8
74 #  define _NEED_IO_FLOAT_LARGE
75 #  define LONG_FLOAT_MAX_DIG    LDTOA_MAX_DIG
76 #  define __lfloat_d_engine     __ldtoa_engine
77 #  define __lfloat_x_engine     __ldtox_engine
78 # endif
79 #endif
80 
81 #ifdef _NEED_IO_DOUBLE
82 # if __SIZEOF_DOUBLE__ == 4
83 #  define _NEED_IO_FLOAT32
84 #  define FLOAT_MAX_DIG         FTOA_MAX_DIG
85 #  define __float_d_engine      __ftoa_engine
86 #  define __float_x_engine      __ftox_engine
87 # elif __SIZEOF_DOUBLE__ == 8
88 #  define _NEED_IO_FLOAT64
89 #  define FLOAT_MAX_DIG         DTOA_MAX_DIG
90 #  define __float_d_engine      __dtoa_engine
91 #  define __float_x_engine      __dtox_engine
92 # endif
93 # define PRINTF_FLOAT_ARG(ap)   (va_arg(ap, double))
94 #endif
95 
96 #ifdef _NEED_IO_FLOAT
97 # define _NEED_IO_FLOAT32
98 # define PRINTF_FLOAT_ARG(ap) (asfloat(va_arg(ap, uint32_t)))
99 # define FLOAT_MAX_DIG   FTOA_MAX_DIG
100 # define __float_d_engine __ftoa_engine
101 # define __float_x_engine __ftox_engine
102 #endif
103 
104 #ifdef _NEED_IO_FLOAT_LARGE
105 #define DTOA_DIGITS     LDTOA_MAX_DIG
106 #elif defined(_NEED_IO_FLOAT64)
107 #define DTOA_DIGITS     DTOA_MAX_DIG
108 #elif defined(_NEED_IO_FLOAT32)
109 #define DTOA_DIGITS     FTOA_MAX_DIG
110 #else
111 #error No float requirement set
112 #endif
113 
114 struct dtoa {
115     int32_t     exp;
116     uint8_t     flags;
117     char        digits[DTOA_DIGITS];
118 };
119 
120 #ifdef _NEED_IO_FLOAT_LARGE
121 int
122 __ldtoa_engine(long double x, struct dtoa *dtoa, int max_digits, bool fmode, int max_decimals);
123 
124 int
125 __ldtox_engine(long double x, struct dtoa *dtoa, int prec, unsigned char case_convert);
126 
127 long double
128 __atold_engine(_u128 m10, int e10);
129 #endif
130 
131 #ifdef _NEED_IO_FLOAT64
132 int
133 __dtoa_engine(FLOAT64 x, struct dtoa *dtoa, int max_digits, bool fmode, int max_decimals);
134 
135 int
136 __dtox_engine(FLOAT64 x, struct dtoa *dtoa, int prec, unsigned char case_convert);
137 
138 FLOAT64
139 __atod_engine(uint64_t m10, int e10);
140 #endif
141 
142 #ifdef _NEED_IO_FLOAT32
143 int __ftoa_engine (float val, struct dtoa *ftoa, int max_digits, bool fmode, int max_decimals);
144 
145 int
146 __ftox_engine(float x, struct dtoa *dtoa, int prec, unsigned char case_convert);
147 
148 float
149 __atof_engine(uint32_t m10, int e10);
150 #endif
151 
152 #endif	/* !_DTOA_H_ */
153