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_ENGINE_H_
30 #define	_DTOA_ENGINE_H_
31 
32 #include <stdlib.h>
33 #include <stdint.h>
34 #include <float.h>
35 #include <stdbool.h>
36 
37 #ifndef DBL_MAX_10_EXP
38 #error DBL_MAX_10_EXP
39 #endif
40 
41 #ifndef DBL_MIN_10_EXP
42 #error DBL_MIN_10_EXP
43 #endif
44 
45 #ifndef DBL_DIG
46 #error DBL_DIG
47 #endif
48 
49 #ifdef PICOLIBC_FLOAT_PRINTF_SCANF
50 
51 #define DTOA_MAX_10_EXP FLT_MAX_10_EXP
52 #define DTOA_MIN_10_EXP FLT_MIN_10_EXP
53 #define DTOA_DIG	9
54 #define DTOA_MAX_DIG 	9
55 
56 #define __dtoa_scale_up __ftoa_scale_up
57 #define __dtoa_scale_down __ftoa_scale_down
58 #define __dtoa_round __ftoa_round
59 #define __atod_engine __atof_engine
60 #define FLOAT float
61 #define UINTFLOAT uint32_t
62 
63 #else
64 
65 #define DTOA_MAX_10_EXP DBL_MAX_10_EXP
66 #define DTOA_MIN_10_EXP DBL_MIN_10_EXP
67 #define DTOA_DIG 	17
68 #define DTOA_MAX_DIG	17
69 #define FLOAT double
70 #define UINTFLOAT uint64_t
71 
72 #endif
73 
74 #define	DTOA_MINUS	1
75 #define	DTOA_ZERO	2
76 #define	DTOA_INF	4
77 #define	DTOA_NAN	8
78 #define	DTOA_CARRY	16	/* Carry was to most significant position. */
79 
80 struct dtoa {
81 	int32_t	exp;
82 	uint8_t	flags;
83 	char	digits[DTOA_MAX_DIG + 1];
84 };
85 
86 int
87 __dtoa_engine(FLOAT x, struct dtoa *dtoa, int max_digits, bool fmode, int max_decimals);
88 
89 extern const FLOAT __dtoa_scale_up[];
90 extern const FLOAT __dtoa_scale_down[];
91 extern const FLOAT __dtoa_round[];
92 
93 #if DTOA_MAX_10_EXP >= 1 && DTOA_MAX_10_EXP < 2
94 #define DTOA_SCALE_UP_NUM 1
95 #endif
96 #if DTOA_MAX_10_EXP >= 2 && DTOA_MAX_10_EXP < 4
97 #define DTOA_SCALE_UP_NUM 2
98 #endif
99 #if DTOA_MAX_10_EXP >= 4 && DTOA_MAX_10_EXP < 8
100 #define DTOA_SCALE_UP_NUM 3
101 #endif
102 #if DTOA_MAX_10_EXP >= 8 && DTOA_MAX_10_EXP < 16
103 #define DTOA_SCALE_UP_NUM 4
104 #endif
105 #if DTOA_MAX_10_EXP >= 16 && DTOA_MAX_10_EXP < 32
106 #define DTOA_SCALE_UP_NUM 5
107 #endif
108 #if DTOA_MAX_10_EXP >= 32 && DTOA_MAX_10_EXP < 64
109 #define DTOA_SCALE_UP_NUM 6
110 #endif
111 #if DTOA_MAX_10_EXP >= 64 && DTOA_MAX_10_EXP < 128
112 #define DTOA_SCALE_UP_NUM 7
113 #endif
114 #if DTOA_MAX_10_EXP >= 128 && DTOA_MAX_10_EXP < 256
115 #define DTOA_SCALE_UP_NUM 8
116 #endif
117 #if DTOA_MAX_10_EXP >= 256 && DTOA_MAX_10_EXP < 512
118 #define DTOA_SCALE_UP_NUM 9
119 #endif
120 #if DTOA_MAX_10_EXP >= 512 && DTOA_MAX_10_EXP < 1024
121 #define DTOA_SCALE_UP_NUM 10
122 #endif
123 #if DTOA_MAX_10_EXP >= 1024 && DTOA_MAX_10_EXP < 2048
124 #define DTOA_SCALE_UP_NUM 11
125 #endif
126 #if DTOA_MAX_10_EXP >= 2048 && DTOA_MAX_10_EXP < 4096
127 #define DTOA_SCALE_UP_NUM 12
128 #endif
129 #if DTOA_MAX_10_EXP >= 4096 && DTOA_MAX_10_EXP < 8192
130 #define DTOA_SCALE_UP_NUM 13
131 #endif
132 #if DTOA_MAX_10_EXP >= 8192 && DTOA_MAX_10_EXP < 16384
133 #define DTOA_SCALE_UP_NUM 14
134 #endif
135 #if DTOA_MAX_10_EXP >= 16384 && DTOA_MAX_10_EXP < 32768
136 #define DTOA_SCALE_UP_NUM 15
137 #endif
138 #if DTOA_MAX_10_EXP >= 32768 && DTOA_MAX_10_EXP < 65536
139 #define DTOA_SCALE_UP_NUM 16
140 #endif
141 #if DTOA_MAX_10_EXP >= 65536 && DTOA_MAX_10_EXP < 131072
142 #define DTOA_SCALE_UP_NUM 17
143 #endif
144 #if DTOA_MIN_10_EXP <= -1 && DTOA_MIN_10_EXP > -2
145 #define DTOA_SCALE_DOWN_NUM 1
146 #endif
147 #if DTOA_MIN_10_EXP <= -2 && DTOA_MIN_10_EXP > -4
148 #define DTOA_SCALE_DOWN_NUM 2
149 #endif
150 #if DTOA_MIN_10_EXP <= -4 && DTOA_MIN_10_EXP > -8
151 #define DTOA_SCALE_DOWN_NUM 3
152 #endif
153 #if DTOA_MIN_10_EXP <= -8 && DTOA_MIN_10_EXP > -16
154 #define DTOA_SCALE_DOWN_NUM 4
155 #endif
156 #if DTOA_MIN_10_EXP <= -16 && DTOA_MIN_10_EXP > -32
157 #define DTOA_SCALE_DOWN_NUM 5
158 #endif
159 #if DTOA_MIN_10_EXP <= -32 && DTOA_MIN_10_EXP > -64
160 #define DTOA_SCALE_DOWN_NUM 6
161 #endif
162 #if DTOA_MIN_10_EXP <= -64 && DTOA_MIN_10_EXP > -128
163 #define DTOA_SCALE_DOWN_NUM 7
164 #endif
165 #if DTOA_MIN_10_EXP <= -128 && DTOA_MIN_10_EXP > -256
166 #define DTOA_SCALE_DOWN_NUM 8
167 #endif
168 #if DTOA_MIN_10_EXP <= -256 && DTOA_MIN_10_EXP > -512
169 #define DTOA_SCALE_DOWN_NUM 9
170 #endif
171 #if DTOA_MIN_10_EXP <= -512 && DTOA_MIN_10_EXP > -1024
172 #define DTOA_SCALE_DOWN_NUM 10
173 #endif
174 #if DTOA_MIN_10_EXP <= -1024 && DTOA_MIN_10_EXP > -2048
175 #define DTOA_SCALE_DOWN_NUM 11
176 #endif
177 #if DTOA_MIN_10_EXP <= -2048 && DTOA_MIN_10_EXP > -4096
178 #define DTOA_SCALE_DOWN_NUM 12
179 #endif
180 #if DTOA_MIN_10_EXP <= -4096 && DTOA_MIN_10_EXP > -8192
181 #define DTOA_SCALE_DOWN_NUM 13
182 #endif
183 #if DTOA_MIN_10_EXP <= -8192 && DTOA_MIN_10_EXP > -16384
184 #define DTOA_SCALE_DOWN_NUM 14
185 #endif
186 #if DTOA_MIN_10_EXP <= -16384 && DTOA_MIN_10_EXP > -32768
187 #define DTOA_SCALE_DOWN_NUM 15
188 #endif
189 #if DTOA_MIN_10_EXP <= -32768 && DTOA_MIN_10_EXP > -65536
190 #define DTOA_SCALE_DOWN_NUM 16
191 #endif
192 #if DTOA_MIN_10_EXP <= -65536 && DTOA_MIN_10_EXP > -131072
193 #define DTOA_SCALE_DOWN_NUM 17
194 #endif
195 
196 #define DTOA_ROUND_NUM (DTOA_DIG + 1)
197 
198 #endif	/* !_DTOA_ENGINE_H_ */
199