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