├── .gitignore ├── .package ├── LICENSE ├── README.md ├── fp.c ├── fp.h └── test.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.dSYM 2 | a.out 3 | .vscode -------------------------------------------------------------------------------- /.package: -------------------------------------------------------------------------------- 1 | file fp.c 2 | file fp.h 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 Joshua J Baker 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fp 2 | 3 | Functions for parsing and converting floating points to/from strings in their shortest, most accurate representation. 4 | 5 | ## Functions 6 | 7 | ```c 8 | /// Convert a double to a string 9 | size_t fp_dtoa(double d, char fmt, char *dst, size_t nbytes); 10 | /// Convert a float to a string 11 | size_t fp_ftoa(float d, char fmt, char *dst, size_t nbytes); 12 | /// Convert a string to a double 13 | bool fp_atod(char *str, size_t len, double *x); 14 | /// Convert a string to a float 15 | bool fp_atof(char *str, size_t len, float *x); 16 | /// Parse floating point info from a data stream and return useful details. 17 | struct fp_info fp_parse(char *str, size_t len); 18 | ``` 19 | 20 | These functions are often faster and more accurate than the ones that are 21 | provided by your standard C compiler, eg. `atof`, `atod`, and `printf`. 22 | This is mostly due to the excellent conversion code provided by the 23 | [ulfjack/ryu](https://github.com/ulfjack/ryu) project. 24 | 25 | Also included is a fast number parser `fp_parse` for reading an IEEE+754 26 | details from a stream of bytes. This is useful when needing to validate 27 | floating points from formats such as JSON, WKT, and SQL. 28 | 29 | ## Quality 30 | 31 | Here's a comparison of the quality of the conversions using the `fp` library 32 | to the standard C printf. 33 | 34 | For the following floating points: 35 | 36 | ``` 37 | 1230456078.90123e10 38 | -7750609.598126 39 | 19688.27920015702 40 | 731575400000 41 | 97967.0432226889 42 | 1216277862.336918 43 | ``` 44 | 45 | Using 'g' format: 46 | 47 | ``` 48 | +---------------------+--------------+ 49 | | fp | printf | 50 | +---------------------+--------------+ 51 | | 1.23045607890123e19 | 1.23046e+19 | 52 | | -7750609.598126 | -7.75061e+06 | 53 | | 19688.27920015702 | 19688.3 | 54 | | 7.315754e11 | 7.31575e+11 | 55 | | 97967.0432226889 | 97967 | 56 | | 1216277862.336918 | 1.21628e+09 | 57 | +---------------------+--------------+ 58 | ``` 59 | 60 | Using 'e' format: 61 | 62 | ``` 63 | +---------------------+---------------+ 64 | | fp | printf | 65 | +---------------------+---------------+ 66 | | 1.23045607890123e19 | 1.230456e+19 | 67 | | -7.750609598126e6 | -7.750610e+06 | 68 | | 1.968827920015702e4 | 1.968828e+04 | 69 | | 7.315754e11 | 7.315754e+11 | 70 | | 9.79670432226889e4 | 9.796704e+04 | 71 | | 1.216277862336918e9 | 1.216278e+09 | 72 | +---------------------+---------------+ 73 | ``` 74 | 75 | Using 'f' format: 76 | 77 | ``` 78 | +----------------------+-----------------------------+ 79 | | fp | printf | 80 | +----------------------+-----------------------------+ 81 | | 12304560789012300000 | 12304560789012299776.000000 | 82 | | -7750609.598126 | -7750609.598126 | 83 | | 19688.27920015702 | 19688.279200 | 84 | | 731575400000 | 731575400000.000000 | 85 | | 97967.0432226889 | 97967.043223 | 86 | | 1216277862.336918 | 1216277862.336918 | 87 | +----------------------+-----------------------------+ 88 | ``` 89 | 90 | ## Using 91 | 92 | Just drop the `fp.c` and `fp.h` files into your project. 93 | 94 | ## Examples 95 | 96 | Convert a double to a string. 97 | 98 | ```c 99 | char buf[32]; 100 | size_t n = fp_dtoa(-112.89123883, 'f', buf, sizeof(buf)); 101 | if (n >= sizeof(buf)) { 102 | // Buffer is too small to store the entire floating point as a string. 103 | abort(); 104 | } 105 | printf("%s\n", buf); 106 | 107 | // Output: -112.89123883 108 | ``` 109 | 110 | Parse a double precision floating point, and then convert it back 111 | 112 | ```c 113 | char *str = "-112.89123883"; 114 | double x; 115 | bool ok = fp_atod(str, strlen(str), &x); 116 | if (!ok) { 117 | // Invalid number 118 | abort(); 119 | } 120 | char buf[32]; 121 | fp_dtoa(x, 'f', buf, sizeof(buf)); 122 | printf("%s\n", buf); 123 | 124 | // Output: -112.89123883 125 | ``` 126 | 127 | Looping over a list of line-delimited floating point string using the 128 | `fp_parse()` function. 129 | 130 | ```c 131 | char *list = 132 | "1230456078.90123e10\n" 133 | "-7750609.598126\n" 134 | "19688.27920015702\n" 135 | "731575400000\n" 136 | "97967.0432226889\n" 137 | "1216277862.336918\n"; 138 | 139 | size_t list_len = strlen(list); 140 | for (size_t i = 0; i < list_len; i++) { 141 | struct fp_info info = fp_parse(list+i, list_len-i); 142 | if (!info.ok) { 143 | // Number is invalid 144 | abort(); 145 | } 146 | printf("%.*s\n", (int)info.len, list+i); 147 | i += info.len; 148 | } 149 | 150 | // 1230456078.90123e10 151 | // -7750609.598126 152 | // 19688.27920015702 153 | // 731575400000 154 | // 97967.0432226889 155 | // 1216277862.336918 156 | ``` 157 | 158 | The `struct fp_info` type store the additional information about the floating 159 | point string. 160 | 161 | ```c 162 | struct fp_info { 163 | bool ok; // number is valid 164 | bool sign; // has sign. Is a negative number 165 | size_t frac; // has dot. Index of '.' or zero if none 166 | size_t exp; // has exponent. Index of 'e' or zero if none 167 | size_t len; // number of bytes parsed 168 | }; 169 | ``` 170 | 171 | 172 | -------------------------------------------------------------------------------- /fp.c: -------------------------------------------------------------------------------- 1 | // https://github.com/tidwall/fp 2 | // 3 | // Copyright 2025 Joshua J Baker. All rights reserved. 4 | // Use of this source code is governed by an MIT-style 5 | // license that can be found in the LICENSE file. 6 | // 7 | // https://github.com/ulfjack/ryu 8 | // 9 | // Copyright 2018 Ulf Adams 10 | // 11 | // The contents of this file may be used under the terms of the Apache License, 12 | // Version 2.0. 13 | // 14 | // (See accompanying file LICENSE-Apache or copy at 15 | // http://www.apache.org/licenses/LICENSE-2.0) 16 | // 17 | // Alternatively, the contents of this file may be used under the terms of 18 | // the Boost Software License, Version 1.0. 19 | // (See accompanying file LICENSE-Boost or copy at 20 | // https://www.boost.org/LICENSE_1_0.txt) 21 | // 22 | // Unless required by applicable law or agreed to in writing, this software 23 | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 24 | // KIND, either express or implied. 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #ifdef FP_STATIC 39 | #define FP_EXTERN static 40 | #endif 41 | 42 | #ifndef FP_EXTERN 43 | #define FP_EXTERN 44 | #endif 45 | 46 | // Returns e == 0 ? 1 : ceil(log_2(5^e)); requires 0 <= e <= 3528. 47 | static inline int32_t pow5bits(const int32_t e) { 48 | // This approximation works up to the point that the multiplication 49 | // overflows at e = 3529. 50 | // If the multiplication were done in 64 bits, it would fail at 5^4004 51 | // which is just greater than 2^9297. 52 | assert(e >= 0); 53 | assert(e <= 3528); 54 | return (int32_t) (((((uint32_t) e) * 1217359) >> 19) + 1); 55 | } 56 | 57 | // Returns floor(log_10(2^e)); requires 0 <= e <= 1650. 58 | static inline uint32_t log10Pow2(const int32_t e) { 59 | // The first value this approximation fails for is 2^1651 which is just 60 | // greater than 10^297. 61 | assert(e >= 0); 62 | assert(e <= 1650); 63 | return (((uint32_t) e) * 78913) >> 18; 64 | } 65 | 66 | // Returns floor(log_10(5^e)); requires 0 <= e <= 2620. 67 | static inline uint32_t log10Pow5(const int32_t e) { 68 | // The first value this approximation fails for is 5^2621 which is just 69 | // greater than 10^1832. 70 | assert(e >= 0); 71 | assert(e <= 2620); 72 | return (((uint32_t) e) * 732923) >> 20; 73 | } 74 | 75 | static inline int copy_special_str(char * const result, const bool sign, 76 | const bool exponent, const bool mantissa) 77 | { 78 | if (mantissa) { 79 | memcpy(result, "NaN", 3); 80 | return 3; 81 | } 82 | if (sign) { 83 | result[0] = '-'; 84 | } 85 | if (exponent) { 86 | memcpy(result + sign, "Infinity", 8); 87 | return sign + 8; 88 | } 89 | memcpy(result + sign, "0E0", 3); 90 | return sign + 3; 91 | } 92 | 93 | static inline uint64_t double_to_bits(const double d) { 94 | uint64_t bits = 0; 95 | memcpy(&bits, &d, sizeof(double)); 96 | return bits; 97 | } 98 | 99 | // A table of all two-digit numbers. This is used to speed up decimal digit 100 | // generation by copying pairs of digits into the final output. 101 | static const char DIGIT_TABLE[200] = { 102 | '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8', 103 | '0','9','1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7', 104 | '1','8','1','9','2','0','2','1','2','2','2','3','2','4','2','5','2','6', 105 | '2','7','2','8','2','9','3','0','3','1','3','2','3','3','3','4','3','5', 106 | '3','6','3','7','3','8','3','9','4','0','4','1','4','2','4','3','4','4', 107 | '4','5','4','6','4','7','4','8','4','9','5','0','5','1','5','2','5','3', 108 | '5','4','5','5','5','6','5','7','5','8','5','9','6','0','6','1','6','2', 109 | '6','3','6','4','6','5','6','6','6','7','6','8','6','9','7','0','7','1', 110 | '7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9','8','0', 111 | '8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9', 112 | '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8', 113 | '9','9', 114 | }; 115 | 116 | // ABSL avoids uint128_t on Win32 even if __SIZEOF_INT128__ is defined. 117 | // Let's do the same for now. 118 | #if defined(__SIZEOF_INT128__) && !defined(_MSC_VER) 119 | #define HAS_UINT128 120 | typedef __uint128_t uint128_t; 121 | #endif 122 | 123 | static inline uint64_t umul128(const uint64_t a, const uint64_t b, uint64_t* 124 | const productHi) 125 | { 126 | // The casts here help MSVC to avoid calls to the __allmul library function. 127 | const uint32_t aLo = (uint32_t)a; 128 | const uint32_t aHi = (uint32_t)(a >> 32); 129 | const uint32_t bLo = (uint32_t)b; 130 | const uint32_t bHi = (uint32_t)(b >> 32); 131 | 132 | const uint64_t b00 = (uint64_t)aLo * bLo; 133 | const uint64_t b01 = (uint64_t)aLo * bHi; 134 | const uint64_t b10 = (uint64_t)aHi * bLo; 135 | const uint64_t b11 = (uint64_t)aHi * bHi; 136 | 137 | const uint32_t b00Lo = (uint32_t)b00; 138 | const uint32_t b00Hi = (uint32_t)(b00 >> 32); 139 | 140 | const uint64_t mid1 = b10 + b00Hi; 141 | const uint32_t mid1Lo = (uint32_t)(mid1); 142 | const uint32_t mid1Hi = (uint32_t)(mid1 >> 32); 143 | 144 | const uint64_t mid2 = b01 + mid1Lo; 145 | const uint32_t mid2Lo = (uint32_t)(mid2); 146 | const uint32_t mid2Hi = (uint32_t)(mid2 >> 32); 147 | 148 | const uint64_t pHi = b11 + mid1Hi + mid2Hi; 149 | const uint64_t pLo = ((uint64_t)mid2Lo << 32) | b00Lo; 150 | 151 | *productHi = pHi; 152 | return pLo; 153 | } 154 | 155 | static inline uint64_t shiftright128(const uint64_t lo, const uint64_t hi, 156 | const uint32_t dist) 157 | { 158 | // We don't need to handle the case dist >= 64 here (see above). 159 | assert(dist < 64); 160 | assert(dist > 0); 161 | return (hi << (64 - dist)) | (lo >> dist); 162 | } 163 | 164 | static inline uint64_t div5(const uint64_t x) { 165 | return x / 5; 166 | } 167 | 168 | static inline uint64_t div10(const uint64_t x) { 169 | return x / 10; 170 | } 171 | 172 | static inline uint64_t div100(const uint64_t x) { 173 | return x / 100; 174 | } 175 | 176 | static inline uint64_t div1e8(const uint64_t x) { 177 | return x / 100000000; 178 | } 179 | 180 | static inline uint64_t div1e9(const uint64_t x) { 181 | return x / 1000000000; 182 | } 183 | 184 | static inline uint32_t mod1e9(const uint64_t x) { 185 | return (uint32_t) (x - 1000000000 * div1e9(x)); 186 | } 187 | 188 | static inline uint32_t pow5Factor(uint64_t value) { 189 | const uint64_t m_inv_5 = 14757395258967641293u; 190 | const uint64_t n_div_5 = 3689348814741910323u; 191 | uint32_t count = 0; 192 | for (;;) { 193 | assert(value != 0); 194 | value *= m_inv_5; 195 | if (value > n_div_5) 196 | break; 197 | ++count; 198 | } 199 | return count; 200 | } 201 | 202 | // Returns true if value is divisible by 5^p. 203 | static inline bool multipleOfPowerOf5(const uint64_t value, const uint32_t p) { 204 | // I tried a case distinction on p, but there was no performance difference. 205 | return pow5Factor(value) >= p; 206 | } 207 | 208 | // Returns true if value is divisible by 2^p. 209 | static inline bool multipleOfPowerOf2(const uint64_t value, const uint32_t p) { 210 | assert(value != 0); 211 | assert(p < 64); 212 | // __builtin_ctzll doesn't appear to be faster here. 213 | return (value & ((1ull << p) - 1)) == 0; 214 | } 215 | 216 | // We need a 64x128-bit multiplication and a subsequent 128-bit shift. 217 | // Multiplication: 218 | // The 64-bit factor is variable and passed in, the 128-bit factor comes 219 | // from a lookup table. We know that the 64-bit factor only has 55 220 | // significant bits (i.e., the 9 topmost bits are zeros). The 128-bit 221 | // factor only has 124 significant bits (i.e., the 4 topmost bits are 222 | // zeros). 223 | // Shift: 224 | // In principle, the multiplication result requires 55 + 124 = 179 bits to 225 | // represent. However, we then shift this value to the right by j, which is 226 | // at least j >= 115, so the result is guaranteed to fit into 179 - 115 = 64 227 | // bits. This means that we only need the topmost 64 significant bits of 228 | // the 64x128-bit multiplication. 229 | // 230 | // There are several ways to do this: 231 | // 1. Best case: the compiler exposes a 128-bit type. 232 | // We perform two 64x64-bit multiplications, add the higher 64 bits of the 233 | // lower result to the higher result, and shift by j - 64 bits. 234 | // 235 | // We explicitly cast from 64-bit to 128-bit, so the compiler can tell 236 | // that these are only 64-bit inputs, and can map these to the best 237 | // possible sequence of assembly instructions. 238 | // x64 machines happen to have matching assembly instructions for 239 | // 64x64-bit multiplications and 128-bit shifts. 240 | // 241 | // 2. Second best case: the compiler exposes intrinsics for the x64 assembly 242 | // instructions mentioned in 1. 243 | // 244 | // 3. We only have 64x64 bit instructions that return the lower 64 bits of 245 | // the result, i.e., we have to use plain C. 246 | // Our inputs are less than the full width, so we have three options: 247 | // a. Ignore this fact and just implement the intrinsics manually. 248 | // b. Split both into 31-bit pieces, which guarantees no internal overflow, 249 | // but requires extra work upfront (unless we change the lookup table). 250 | // c. Split only the first factor into 31-bit pieces, which also guarantees 251 | // no internal overflow, but requires extra work since the intermediate 252 | // results are not perfectly aligned. 253 | #if defined(HAS_UINT128) 254 | 255 | // Best case: use 128-bit type. 256 | static inline uint64_t mulShift64(const uint64_t m, const uint64_t* const mul, 257 | const int32_t j) 258 | { 259 | const uint128_t b0 = ((uint128_t) m) * mul[0]; 260 | const uint128_t b2 = ((uint128_t) m) * mul[1]; 261 | return (uint64_t) (((b0 >> 64) + b2) >> (j - 64)); 262 | } 263 | 264 | static inline uint64_t mulShiftAll64(const uint64_t m, const uint64_t* 265 | const mul, const int32_t j, uint64_t* const vp, uint64_t* const vm, 266 | const uint32_t mmShift) 267 | { 268 | *vp = mulShift64(4 * m + 2, mul, j); 269 | *vm = mulShift64(4 * m - 1 - mmShift, mul, j); 270 | return mulShift64(4 * m, mul, j); 271 | } 272 | 273 | #else 274 | 275 | static inline uint64_t mulShift64(const uint64_t m, const uint64_t* const mul, 276 | const int32_t j) 277 | { 278 | // m is maximum 55 bits 279 | uint64_t high1; // 128 280 | const uint64_t low1 = umul128(m, mul[1], &high1); // 64 281 | uint64_t high0; // 64 282 | umul128(m, mul[0], &high0); // 0 283 | const uint64_t sum = high0 + low1; 284 | if (sum < high0) { 285 | ++high1; // overflow into high1 286 | } 287 | return shiftright128(sum, high1, j - 64); 288 | } 289 | 290 | // This is faster if we don't have a 64x64->128-bit multiplication. 291 | static inline uint64_t mulShiftAll64(uint64_t m, const uint64_t* const mul, 292 | const int32_t j, uint64_t* const vp, uint64_t* const vm, 293 | const uint32_t mmShift) 294 | { 295 | m <<= 1; 296 | // m is maximum 55 bits 297 | uint64_t tmp; 298 | const uint64_t lo = umul128(m, mul[0], &tmp); 299 | uint64_t hi; 300 | const uint64_t mid = tmp + umul128(m, mul[1], &hi); 301 | hi += mid < tmp; // overflow into hi 302 | 303 | const uint64_t lo2 = lo + mul[0]; 304 | const uint64_t mid2 = mid + mul[1] + (lo2 < lo); 305 | const uint64_t hi2 = hi + (mid2 < mid); 306 | *vp = shiftright128(mid2, hi2, (uint32_t) (j - 64 - 1)); 307 | 308 | if (mmShift == 1) { 309 | const uint64_t lo3 = lo - mul[0]; 310 | const uint64_t mid3 = mid - mul[1] - (lo3 > lo); 311 | const uint64_t hi3 = hi - (mid3 > mid); 312 | *vm = shiftright128(mid3, hi3, (uint32_t) (j - 64 - 1)); 313 | } else { 314 | const uint64_t lo3 = lo + lo; 315 | const uint64_t mid3 = mid + mid + (lo3 < lo); 316 | const uint64_t hi3 = hi + hi + (mid3 < mid); 317 | const uint64_t lo4 = lo3 - mul[0]; 318 | const uint64_t mid4 = mid3 - mul[1] - (lo4 > lo3); 319 | const uint64_t hi4 = hi3 - (mid4 > mid3); 320 | *vm = shiftright128(mid4, hi4, (uint32_t) (j - 64)); 321 | } 322 | 323 | return shiftright128(mid, hi, (uint32_t) (j - 64 - 1)); 324 | } 325 | 326 | #endif 327 | 328 | // These tables are generated by PrintDoubleLookupTable. 329 | #define DOUBLE_POW5_INV_BITCOUNT 125 330 | #define DOUBLE_POW5_BITCOUNT 125 331 | 332 | #define DOUBLE_POW5_INV_TABLE_SIZE 342 333 | #define DOUBLE_POW5_TABLE_SIZE 326 334 | 335 | static const uint64_t DOUBLE_POW5_INV_SPLIT[DOUBLE_POW5_INV_TABLE_SIZE][2] = { 336 | { 1u, 2305843009213693952u }, 337 | { 11068046444225730970u, 1844674407370955161u }, 338 | { 5165088340638674453u, 1475739525896764129u }, 339 | { 7821419487252849886u, 1180591620717411303u }, 340 | { 8824922364862649494u, 1888946593147858085u }, 341 | { 7059937891890119595u, 1511157274518286468u }, 342 | { 13026647942995916322u, 1208925819614629174u }, 343 | { 9774590264567735146u, 1934281311383406679u }, 344 | { 11509021026396098440u, 1547425049106725343u }, 345 | { 16585914450600699399u, 1237940039285380274u }, 346 | { 15469416676735388068u, 1980704062856608439u }, 347 | { 16064882156130220778u, 1584563250285286751u }, 348 | { 9162556910162266299u, 1267650600228229401u }, 349 | { 7281393426775805432u, 2028240960365167042u }, 350 | { 16893161185646375315u, 1622592768292133633u }, 351 | { 2446482504291369283u, 1298074214633706907u }, 352 | { 7603720821608101175u, 2076918743413931051u }, 353 | { 2393627842544570617u, 1661534994731144841u }, 354 | { 16672297533003297786u, 1329227995784915872u }, 355 | { 11918280793837635165u, 2126764793255865396u }, 356 | { 5845275820328197809u, 1701411834604692317u }, 357 | { 15744267100488289217u, 1361129467683753853u }, 358 | { 3054734472329800808u, 2177807148294006166u }, 359 | { 17201182836831481939u, 1742245718635204932u }, 360 | { 6382248639981364905u, 1393796574908163946u }, 361 | { 2832900194486363201u, 2230074519853062314u }, 362 | { 5955668970331000884u, 1784059615882449851u }, 363 | { 1075186361522890384u, 1427247692705959881u }, 364 | { 12788344622662355584u, 2283596308329535809u }, 365 | { 13920024512871794791u, 1826877046663628647u }, 366 | { 3757321980813615186u, 1461501637330902918u }, 367 | { 10384555214134712795u, 1169201309864722334u }, 368 | { 5547241898389809503u, 1870722095783555735u }, 369 | { 4437793518711847602u, 1496577676626844588u }, 370 | { 10928932444453298728u, 1197262141301475670u }, 371 | { 17486291911125277965u, 1915619426082361072u }, 372 | { 6610335899416401726u, 1532495540865888858u }, 373 | { 12666966349016942027u, 1225996432692711086u }, 374 | { 12888448528943286597u, 1961594292308337738u }, 375 | { 17689456452638449924u, 1569275433846670190u }, 376 | { 14151565162110759939u, 1255420347077336152u }, 377 | { 7885109000409574610u, 2008672555323737844u }, 378 | { 9997436015069570011u, 1606938044258990275u }, 379 | { 7997948812055656009u, 1285550435407192220u }, 380 | { 12796718099289049614u, 2056880696651507552u }, 381 | { 2858676849947419045u, 1645504557321206042u }, 382 | { 13354987924183666206u, 1316403645856964833u }, 383 | { 17678631863951955605u, 2106245833371143733u }, 384 | { 3074859046935833515u, 1684996666696914987u }, 385 | { 13527933681774397782u, 1347997333357531989u }, 386 | { 10576647446613305481u, 2156795733372051183u }, 387 | { 15840015586774465031u, 1725436586697640946u }, 388 | { 8982663654677661702u, 1380349269358112757u }, 389 | { 18061610662226169046u, 2208558830972980411u }, 390 | { 10759939715039024913u, 1766847064778384329u }, 391 | { 12297300586773130254u, 1413477651822707463u }, 392 | { 15986332124095098083u, 2261564242916331941u }, 393 | { 9099716884534168143u, 1809251394333065553u }, 394 | { 14658471137111155161u, 1447401115466452442u }, 395 | { 4348079280205103483u, 1157920892373161954u }, 396 | { 14335624477811986218u, 1852673427797059126u }, 397 | { 7779150767507678651u, 1482138742237647301u }, 398 | { 2533971799264232598u, 1185710993790117841u }, 399 | { 15122401323048503126u, 1897137590064188545u }, 400 | { 12097921058438802501u, 1517710072051350836u }, 401 | { 5988988032009131678u, 1214168057641080669u }, 402 | { 16961078480698431330u, 1942668892225729070u }, 403 | { 13568862784558745064u, 1554135113780583256u }, 404 | { 7165741412905085728u, 1243308091024466605u }, 405 | { 11465186260648137165u, 1989292945639146568u }, 406 | { 16550846638002330379u, 1591434356511317254u }, 407 | { 16930026125143774626u, 1273147485209053803u }, 408 | { 4951948911778577463u, 2037035976334486086u }, 409 | { 272210314680951647u, 1629628781067588869u }, 410 | { 3907117066486671641u, 1303703024854071095u }, 411 | { 6251387306378674625u, 2085924839766513752u }, 412 | { 16069156289328670670u, 1668739871813211001u }, 413 | { 9165976216721026213u, 1334991897450568801u }, 414 | { 7286864317269821294u, 2135987035920910082u }, 415 | { 16897537898041588005u, 1708789628736728065u }, 416 | { 13518030318433270404u, 1367031702989382452u }, 417 | { 6871453250525591353u, 2187250724783011924u }, 418 | { 9186511415162383406u, 1749800579826409539u }, 419 | { 11038557946871817048u, 1399840463861127631u }, 420 | { 10282995085511086630u, 2239744742177804210u }, 421 | { 8226396068408869304u, 1791795793742243368u }, 422 | { 13959814484210916090u, 1433436634993794694u }, 423 | { 11267656730511734774u, 2293498615990071511u }, 424 | { 5324776569667477496u, 1834798892792057209u }, 425 | { 7949170070475892320u, 1467839114233645767u }, 426 | { 17427382500606444826u, 1174271291386916613u }, 427 | { 5747719112518849781u, 1878834066219066582u }, 428 | { 15666221734240810795u, 1503067252975253265u }, 429 | { 12532977387392648636u, 1202453802380202612u }, 430 | { 5295368560860596524u, 1923926083808324180u }, 431 | { 4236294848688477220u, 1539140867046659344u }, 432 | { 7078384693692692099u, 1231312693637327475u }, 433 | { 11325415509908307358u, 1970100309819723960u }, 434 | { 9060332407926645887u, 1576080247855779168u }, 435 | { 14626963555825137356u, 1260864198284623334u }, 436 | { 12335095245094488799u, 2017382717255397335u }, 437 | { 9868076196075591040u, 1613906173804317868u }, 438 | { 15273158586344293478u, 1291124939043454294u }, 439 | { 13369007293925138595u, 2065799902469526871u }, 440 | { 7005857020398200553u, 1652639921975621497u }, 441 | { 16672732060544291412u, 1322111937580497197u }, 442 | { 11918976037903224966u, 2115379100128795516u }, 443 | { 5845832015580669650u, 1692303280103036413u }, 444 | { 12055363241948356366u, 1353842624082429130u }, 445 | { 841837113407818570u, 2166148198531886609u }, 446 | { 4362818505468165179u, 1732918558825509287u }, 447 | { 14558301248600263113u, 1386334847060407429u }, 448 | { 12225235553534690011u, 2218135755296651887u }, 449 | { 2401490813343931363u, 1774508604237321510u }, 450 | { 1921192650675145090u, 1419606883389857208u }, 451 | { 17831303500047873437u, 2271371013423771532u }, 452 | { 6886345170554478103u, 1817096810739017226u }, 453 | { 1819727321701672159u, 1453677448591213781u }, 454 | { 16213177116328979020u, 1162941958872971024u }, 455 | { 14873036941900635463u, 1860707134196753639u }, 456 | { 15587778368262418694u, 1488565707357402911u }, 457 | { 8780873879868024632u, 1190852565885922329u }, 458 | { 2981351763563108441u, 1905364105417475727u }, 459 | { 13453127855076217722u, 1524291284333980581u }, 460 | { 7073153469319063855u, 1219433027467184465u }, 461 | { 11317045550910502167u, 1951092843947495144u }, 462 | { 12742985255470312057u, 1560874275157996115u }, 463 | { 10194388204376249646u, 1248699420126396892u }, 464 | { 1553625868034358140u, 1997919072202235028u }, 465 | { 8621598323911307159u, 1598335257761788022u }, 466 | { 17965325103354776697u, 1278668206209430417u }, 467 | { 13987124906400001422u, 2045869129935088668u }, 468 | { 121653480894270168u, 1636695303948070935u }, 469 | { 97322784715416134u, 1309356243158456748u }, 470 | { 14913111714512307107u, 2094969989053530796u }, 471 | { 8241140556867935363u, 1675975991242824637u }, 472 | { 17660958889720079260u, 1340780792994259709u }, 473 | { 17189487779326395846u, 2145249268790815535u }, 474 | { 13751590223461116677u, 1716199415032652428u }, 475 | { 18379969808252713988u, 1372959532026121942u }, 476 | { 14650556434236701088u, 2196735251241795108u }, 477 | { 652398703163629901u, 1757388200993436087u }, 478 | { 11589965406756634890u, 1405910560794748869u }, 479 | { 7475898206584884855u, 2249456897271598191u }, 480 | { 2291369750525997561u, 1799565517817278553u }, 481 | { 9211793429904618695u, 1439652414253822842u }, 482 | { 18428218302589300235u, 2303443862806116547u }, 483 | { 7363877012587619542u, 1842755090244893238u }, 484 | { 13269799239553916280u, 1474204072195914590u }, 485 | { 10615839391643133024u, 1179363257756731672u }, 486 | { 2227947767661371545u, 1886981212410770676u }, 487 | { 16539753473096738529u, 1509584969928616540u }, 488 | { 13231802778477390823u, 1207667975942893232u }, 489 | { 6413489186596184024u, 1932268761508629172u }, 490 | { 16198837793502678189u, 1545815009206903337u }, 491 | { 5580372605318321905u, 1236652007365522670u }, 492 | { 8928596168509315048u, 1978643211784836272u }, 493 | { 18210923379033183008u, 1582914569427869017u }, 494 | { 7190041073742725760u, 1266331655542295214u }, 495 | { 436019273762630246u, 2026130648867672343u }, 496 | { 7727513048493924843u, 1620904519094137874u }, 497 | { 9871359253537050198u, 1296723615275310299u }, 498 | { 4726128361433549347u, 2074757784440496479u }, 499 | { 7470251503888749801u, 1659806227552397183u }, 500 | { 13354898832594820487u, 1327844982041917746u }, 501 | { 13989140502667892133u, 2124551971267068394u }, 502 | { 14880661216876224029u, 1699641577013654715u }, 503 | { 11904528973500979224u, 1359713261610923772u }, 504 | { 4289851098633925465u, 2175541218577478036u }, 505 | { 18189276137874781665u, 1740432974861982428u }, 506 | { 3483374466074094362u, 1392346379889585943u }, 507 | { 1884050330976640656u, 2227754207823337509u }, 508 | { 5196589079523222848u, 1782203366258670007u }, 509 | { 15225317707844309248u, 1425762693006936005u }, 510 | { 5913764258841343181u, 2281220308811097609u }, 511 | { 8420360221814984868u, 1824976247048878087u }, 512 | { 17804334621677718864u, 1459980997639102469u }, 513 | { 17932816512084085415u, 1167984798111281975u }, 514 | { 10245762345624985047u, 1868775676978051161u }, 515 | { 4507261061758077715u, 1495020541582440929u }, 516 | { 7295157664148372495u, 1196016433265952743u }, 517 | { 7982903447895485668u, 1913626293225524389u }, 518 | { 10075671573058298858u, 1530901034580419511u }, 519 | { 4371188443704728763u, 1224720827664335609u }, 520 | { 14372599139411386667u, 1959553324262936974u }, 521 | { 15187428126271019657u, 1567642659410349579u }, 522 | { 15839291315758726049u, 1254114127528279663u }, 523 | { 3206773216762499739u, 2006582604045247462u }, 524 | { 13633465017635730761u, 1605266083236197969u }, 525 | { 14596120828850494932u, 1284212866588958375u }, 526 | { 4907049252451240275u, 2054740586542333401u }, 527 | { 236290587219081897u, 1643792469233866721u }, 528 | { 14946427728742906810u, 1315033975387093376u }, 529 | { 16535586736504830250u, 2104054360619349402u }, 530 | { 5849771759720043554u, 1683243488495479522u }, 531 | { 15747863852001765813u, 1346594790796383617u }, 532 | { 10439186904235184007u, 2154551665274213788u }, 533 | { 15730047152871967852u, 1723641332219371030u }, 534 | { 12584037722297574282u, 1378913065775496824u }, 535 | { 9066413911450387881u, 2206260905240794919u }, 536 | { 10942479943902220628u, 1765008724192635935u }, 537 | { 8753983955121776503u, 1412006979354108748u }, 538 | { 10317025513452932081u, 2259211166966573997u }, 539 | { 874922781278525018u, 1807368933573259198u }, 540 | { 8078635854506640661u, 1445895146858607358u }, 541 | { 13841606313089133175u, 1156716117486885886u }, 542 | { 14767872471458792434u, 1850745787979017418u }, 543 | { 746251532941302978u, 1480596630383213935u }, 544 | { 597001226353042382u, 1184477304306571148u }, 545 | { 15712597221132509104u, 1895163686890513836u }, 546 | { 8880728962164096960u, 1516130949512411069u }, 547 | { 10793931984473187891u, 1212904759609928855u }, 548 | { 17270291175157100626u, 1940647615375886168u }, 549 | { 2748186495899949531u, 1552518092300708935u }, 550 | { 2198549196719959625u, 1242014473840567148u }, 551 | { 18275073973719576693u, 1987223158144907436u }, 552 | { 10930710364233751031u, 1589778526515925949u }, 553 | { 12433917106128911148u, 1271822821212740759u }, 554 | { 8826220925580526867u, 2034916513940385215u }, 555 | { 7060976740464421494u, 1627933211152308172u }, 556 | { 16716827836597268165u, 1302346568921846537u }, 557 | { 11989529279587987770u, 2083754510274954460u }, 558 | { 9591623423670390216u, 1667003608219963568u }, 559 | { 15051996368420132820u, 1333602886575970854u }, 560 | { 13015147745246481542u, 2133764618521553367u }, 561 | { 3033420566713364587u, 1707011694817242694u }, 562 | { 6116085268112601993u, 1365609355853794155u }, 563 | { 9785736428980163188u, 2184974969366070648u }, 564 | { 15207286772667951197u, 1747979975492856518u }, 565 | { 1097782973908629988u, 1398383980394285215u }, 566 | { 1756452758253807981u, 2237414368630856344u }, 567 | { 5094511021344956708u, 1789931494904685075u }, 568 | { 4075608817075965366u, 1431945195923748060u }, 569 | { 6520974107321544586u, 2291112313477996896u }, 570 | { 1527430471115325346u, 1832889850782397517u }, 571 | { 12289990821117991246u, 1466311880625918013u }, 572 | { 17210690286378213644u, 1173049504500734410u }, 573 | { 9090360384495590213u, 1876879207201175057u }, 574 | { 18340334751822203140u, 1501503365760940045u }, 575 | { 14672267801457762512u, 1201202692608752036u }, 576 | { 16096930852848599373u, 1921924308174003258u }, 577 | { 1809498238053148529u, 1537539446539202607u }, 578 | { 12515645034668249793u, 1230031557231362085u }, 579 | { 1578287981759648052u, 1968050491570179337u }, 580 | { 12330676829633449412u, 1574440393256143469u }, 581 | { 13553890278448669853u, 1259552314604914775u }, 582 | { 3239480371808320148u, 2015283703367863641u }, 583 | { 17348979556414297411u, 1612226962694290912u }, 584 | { 6500486015647617283u, 1289781570155432730u }, 585 | { 10400777625036187652u, 2063650512248692368u }, 586 | { 15699319729512770768u, 1650920409798953894u }, 587 | { 16248804598352126938u, 1320736327839163115u }, 588 | { 7551343283653851484u, 2113178124542660985u }, 589 | { 6041074626923081187u, 1690542499634128788u }, 590 | { 12211557331022285596u, 1352433999707303030u }, 591 | { 1091747655926105338u, 2163894399531684849u }, 592 | { 4562746939482794594u, 1731115519625347879u }, 593 | { 7339546366328145998u, 1384892415700278303u }, 594 | { 8053925371383123274u, 2215827865120445285u }, 595 | { 6443140297106498619u, 1772662292096356228u }, 596 | { 12533209867169019542u, 1418129833677084982u }, 597 | { 5295740528502789974u, 2269007733883335972u }, 598 | { 15304638867027962949u, 1815206187106668777u }, 599 | { 4865013464138549713u, 1452164949685335022u }, 600 | { 14960057215536570740u, 1161731959748268017u }, 601 | { 9178696285890871890u, 1858771135597228828u }, 602 | { 14721654658196518159u, 1487016908477783062u }, 603 | { 4398626097073393881u, 1189613526782226450u }, 604 | { 7037801755317430209u, 1903381642851562320u }, 605 | { 5630241404253944167u, 1522705314281249856u }, 606 | { 814844308661245011u, 1218164251424999885u }, 607 | { 1303750893857992017u, 1949062802279999816u }, 608 | { 15800395974054034906u, 1559250241823999852u }, 609 | { 5261619149759407279u, 1247400193459199882u }, 610 | { 12107939454356961969u, 1995840309534719811u }, 611 | { 5997002748743659252u, 1596672247627775849u }, 612 | { 8486951013736837725u, 1277337798102220679u }, 613 | { 2511075177753209390u, 2043740476963553087u }, 614 | { 13076906586428298482u, 1634992381570842469u }, 615 | { 14150874083884549109u, 1307993905256673975u }, 616 | { 4194654460505726958u, 2092790248410678361u }, 617 | { 18113118827372222859u, 1674232198728542688u }, 618 | { 3422448617672047318u, 1339385758982834151u }, 619 | { 16543964232501006678u, 2143017214372534641u }, 620 | { 9545822571258895019u, 1714413771498027713u }, 621 | { 15015355686490936662u, 1371531017198422170u }, 622 | { 5577825024675947042u, 2194449627517475473u }, 623 | { 11840957649224578280u, 1755559702013980378u }, 624 | { 16851463748863483271u, 1404447761611184302u }, 625 | { 12204946739213931940u, 2247116418577894884u }, 626 | { 13453306206113055875u, 1797693134862315907u }, 627 | { 3383947335406624054u, 1438154507889852726u }, 628 | { 16482362180876329456u, 2301047212623764361u }, 629 | { 9496540929959153242u, 1840837770099011489u }, 630 | { 11286581558709232917u, 1472670216079209191u }, 631 | { 5339916432225476010u, 1178136172863367353u }, 632 | { 4854517476818851293u, 1885017876581387765u }, 633 | { 3883613981455081034u, 1508014301265110212u }, 634 | { 14174937629389795797u, 1206411441012088169u }, 635 | { 11611853762797942306u, 1930258305619341071u }, 636 | { 5600134195496443521u, 1544206644495472857u }, 637 | { 15548153800622885787u, 1235365315596378285u }, 638 | { 6430302007287065643u, 1976584504954205257u }, 639 | { 16212288050055383484u, 1581267603963364205u }, 640 | { 12969830440044306787u, 1265014083170691364u }, 641 | { 9683682259845159889u, 2024022533073106183u }, 642 | { 15125643437359948558u, 1619218026458484946u }, 643 | { 8411165935146048523u, 1295374421166787957u }, 644 | { 17147214310975587960u, 2072599073866860731u }, 645 | { 10028422634038560045u, 1658079259093488585u }, 646 | { 8022738107230848036u, 1326463407274790868u }, 647 | { 9147032156827446534u, 2122341451639665389u }, 648 | { 11006974540203867551u, 1697873161311732311u }, 649 | { 5116230817421183718u, 1358298529049385849u }, 650 | { 15564666937357714594u, 2173277646479017358u }, 651 | { 1383687105660440706u, 1738622117183213887u }, 652 | { 12174996128754083534u, 1390897693746571109u }, 653 | { 8411947361780802685u, 2225436309994513775u }, 654 | { 6729557889424642148u, 1780349047995611020u }, 655 | { 5383646311539713719u, 1424279238396488816u }, 656 | { 1235136468979721303u, 2278846781434382106u }, 657 | { 15745504434151418335u, 1823077425147505684u }, 658 | { 16285752362063044992u, 1458461940118004547u }, 659 | { 5649904260166615347u, 1166769552094403638u }, 660 | { 5350498001524674232u, 1866831283351045821u }, 661 | { 591049586477829062u, 1493465026680836657u }, 662 | { 11540886113407994219u, 1194772021344669325u }, 663 | { 18673707743239135u, 1911635234151470921u }, 664 | { 14772334225162232601u, 1529308187321176736u }, 665 | { 8128518565387875758u, 1223446549856941389u }, 666 | { 1937583260394870242u, 1957514479771106223u }, 667 | { 8928764237799716840u, 1566011583816884978u }, 668 | { 14521709019723594119u, 1252809267053507982u }, 669 | { 8477339172590109297u, 2004494827285612772u }, 670 | { 17849917782297818407u, 1603595861828490217u }, 671 | { 6901236596354434079u, 1282876689462792174u }, 672 | { 18420676183650915173u, 2052602703140467478u }, 673 | { 3668494502695001169u, 1642082162512373983u }, 674 | { 10313493231639821582u, 1313665730009899186u }, 675 | { 9122891541139893884u, 2101865168015838698u }, 676 | { 14677010862395735754u, 1681492134412670958u }, 677 | { 673562245690857633u, 1345193707530136767u } 678 | }; 679 | 680 | static const uint64_t DOUBLE_POW5_SPLIT[DOUBLE_POW5_TABLE_SIZE][2] = { 681 | { 0u, 1152921504606846976u }, 682 | { 0u, 1441151880758558720u }, 683 | { 0u, 1801439850948198400u }, 684 | { 0u, 2251799813685248000u }, 685 | { 0u, 1407374883553280000u }, 686 | { 0u, 1759218604441600000u }, 687 | { 0u, 2199023255552000000u }, 688 | { 0u, 1374389534720000000u }, 689 | { 0u, 1717986918400000000u }, 690 | { 0u, 2147483648000000000u }, 691 | { 0u, 1342177280000000000u }, 692 | { 0u, 1677721600000000000u }, 693 | { 0u, 2097152000000000000u }, 694 | { 0u, 1310720000000000000u }, 695 | { 0u, 1638400000000000000u }, 696 | { 0u, 2048000000000000000u }, 697 | { 0u, 1280000000000000000u }, 698 | { 0u, 1600000000000000000u }, 699 | { 0u, 2000000000000000000u }, 700 | { 0u, 1250000000000000000u }, 701 | { 0u, 1562500000000000000u }, 702 | { 0u, 1953125000000000000u }, 703 | { 0u, 1220703125000000000u }, 704 | { 0u, 1525878906250000000u }, 705 | { 0u, 1907348632812500000u }, 706 | { 0u, 1192092895507812500u }, 707 | { 0u, 1490116119384765625u }, 708 | { 4611686018427387904u, 1862645149230957031u }, 709 | { 9799832789158199296u, 1164153218269348144u }, 710 | { 12249790986447749120u, 1455191522836685180u }, 711 | { 15312238733059686400u, 1818989403545856475u }, 712 | { 14528612397897220096u, 2273736754432320594u }, 713 | { 13692068767113150464u, 1421085471520200371u }, 714 | { 12503399940464050176u, 1776356839400250464u }, 715 | { 15629249925580062720u, 2220446049250313080u }, 716 | { 9768281203487539200u, 1387778780781445675u }, 717 | { 7598665485932036096u, 1734723475976807094u }, 718 | { 274959820560269312u, 2168404344971008868u }, 719 | { 9395221924704944128u, 1355252715606880542u }, 720 | { 2520655369026404352u, 1694065894508600678u }, 721 | { 12374191248137781248u, 2117582368135750847u }, 722 | { 14651398557727195136u, 1323488980084844279u }, 723 | { 13702562178731606016u, 1654361225106055349u }, 724 | { 3293144668132343808u, 2067951531382569187u }, 725 | { 18199116482078572544u, 1292469707114105741u }, 726 | { 8913837547316051968u, 1615587133892632177u }, 727 | { 15753982952572452864u, 2019483917365790221u }, 728 | { 12152082354571476992u, 1262177448353618888u }, 729 | { 15190102943214346240u, 1577721810442023610u }, 730 | { 9764256642163156992u, 1972152263052529513u }, 731 | { 17631875447420442880u, 1232595164407830945u }, 732 | { 8204786253993389888u, 1540743955509788682u }, 733 | { 1032610780636961552u, 1925929944387235853u }, 734 | { 2951224747111794922u, 1203706215242022408u }, 735 | { 3689030933889743652u, 1504632769052528010u }, 736 | { 13834660704216955373u, 1880790961315660012u }, 737 | { 17870034976990372916u, 1175494350822287507u }, 738 | { 17725857702810578241u, 1469367938527859384u }, 739 | { 3710578054803671186u, 1836709923159824231u }, 740 | { 26536550077201078u, 2295887403949780289u }, 741 | { 11545800389866720434u, 1434929627468612680u }, 742 | { 14432250487333400542u, 1793662034335765850u }, 743 | { 8816941072311974870u, 2242077542919707313u }, 744 | { 17039803216263454053u, 1401298464324817070u }, 745 | { 12076381983474541759u, 1751623080406021338u }, 746 | { 5872105442488401391u, 2189528850507526673u }, 747 | { 15199280947623720629u, 1368455531567204170u }, 748 | { 9775729147674874978u, 1710569414459005213u }, 749 | { 16831347453020981627u, 2138211768073756516u }, 750 | { 1296220121283337709u, 1336382355046097823u }, 751 | { 15455333206886335848u, 1670477943807622278u }, 752 | { 10095794471753144002u, 2088097429759527848u }, 753 | { 6309871544845715001u, 1305060893599704905u }, 754 | { 12499025449484531656u, 1631326116999631131u }, 755 | { 11012095793428276666u, 2039157646249538914u }, 756 | { 11494245889320060820u, 1274473528905961821u }, 757 | { 532749306367912313u, 1593091911132452277u }, 758 | { 5277622651387278295u, 1991364888915565346u }, 759 | { 7910200175544436838u, 1244603055572228341u }, 760 | { 14499436237857933952u, 1555753819465285426u }, 761 | { 8900923260467641632u, 1944692274331606783u }, 762 | { 12480606065433357876u, 1215432671457254239u }, 763 | { 10989071563364309441u, 1519290839321567799u }, 764 | { 9124653435777998898u, 1899113549151959749u }, 765 | { 8008751406574943263u, 1186945968219974843u }, 766 | { 5399253239791291175u, 1483682460274968554u }, 767 | { 15972438586593889776u, 1854603075343710692u }, 768 | { 759402079766405302u, 1159126922089819183u }, 769 | { 14784310654990170340u, 1448908652612273978u }, 770 | { 9257016281882937117u, 1811135815765342473u }, 771 | { 16182956370781059300u, 2263919769706678091u }, 772 | { 7808504722524468110u, 1414949856066673807u }, 773 | { 5148944884728197234u, 1768687320083342259u }, 774 | { 1824495087482858639u, 2210859150104177824u }, 775 | { 1140309429676786649u, 1381786968815111140u }, 776 | { 1425386787095983311u, 1727233711018888925u }, 777 | { 6393419502297367043u, 2159042138773611156u }, 778 | { 13219259225790630210u, 1349401336733506972u }, 779 | { 16524074032238287762u, 1686751670916883715u }, 780 | { 16043406521870471799u, 2108439588646104644u }, 781 | { 803757039314269066u, 1317774742903815403u }, 782 | { 14839754354425000045u, 1647218428629769253u }, 783 | { 4714634887749086344u, 2059023035787211567u }, 784 | { 9864175832484260821u, 1286889397367007229u }, 785 | { 16941905809032713930u, 1608611746708759036u }, 786 | { 2730638187581340797u, 2010764683385948796u }, 787 | { 10930020904093113806u, 1256727927116217997u }, 788 | { 18274212148543780162u, 1570909908895272496u }, 789 | { 4396021111970173586u, 1963637386119090621u }, 790 | { 5053356204195052443u, 1227273366324431638u }, 791 | { 15540067292098591362u, 1534091707905539547u }, 792 | { 14813398096695851299u, 1917614634881924434u }, 793 | { 13870059828862294966u, 1198509146801202771u }, 794 | { 12725888767650480803u, 1498136433501503464u }, 795 | { 15907360959563101004u, 1872670541876879330u }, 796 | { 14553786618154326031u, 1170419088673049581u }, 797 | { 4357175217410743827u, 1463023860841311977u }, 798 | { 10058155040190817688u, 1828779826051639971u }, 799 | { 7961007781811134206u, 2285974782564549964u }, 800 | { 14199001900486734687u, 1428734239102843727u }, 801 | { 13137066357181030455u, 1785917798878554659u }, 802 | { 11809646928048900164u, 2232397248598193324u }, 803 | { 16604401366885338411u, 1395248280373870827u }, 804 | { 16143815690179285109u, 1744060350467338534u }, 805 | { 10956397575869330579u, 2180075438084173168u }, 806 | { 6847748484918331612u, 1362547148802608230u }, 807 | { 17783057643002690323u, 1703183936003260287u }, 808 | { 17617136035325974999u, 2128979920004075359u }, 809 | { 17928239049719816230u, 1330612450002547099u }, 810 | { 17798612793722382384u, 1663265562503183874u }, 811 | { 13024893955298202172u, 2079081953128979843u }, 812 | { 5834715712847682405u, 1299426220705612402u }, 813 | { 16516766677914378815u, 1624282775882015502u }, 814 | { 11422586310538197711u, 2030353469852519378u }, 815 | { 11750802462513761473u, 1268970918657824611u }, 816 | { 10076817059714813937u, 1586213648322280764u }, 817 | { 12596021324643517422u, 1982767060402850955u }, 818 | { 5566670318688504437u, 1239229412751781847u }, 819 | { 2346651879933242642u, 1549036765939727309u }, 820 | { 7545000868343941206u, 1936295957424659136u }, 821 | { 4715625542714963254u, 1210184973390411960u }, 822 | { 5894531928393704067u, 1512731216738014950u }, 823 | { 16591536947346905892u, 1890914020922518687u }, 824 | { 17287239619732898039u, 1181821263076574179u }, 825 | { 16997363506238734644u, 1477276578845717724u }, 826 | { 2799960309088866689u, 1846595723557147156u }, 827 | { 10973347230035317489u, 1154122327223216972u }, 828 | { 13716684037544146861u, 1442652909029021215u }, 829 | { 12534169028502795672u, 1803316136286276519u }, 830 | { 11056025267201106687u, 2254145170357845649u }, 831 | { 18439230838069161439u, 1408840731473653530u }, 832 | { 13825666510731675991u, 1761050914342066913u }, 833 | { 3447025083132431277u, 2201313642927583642u }, 834 | { 6766076695385157452u, 1375821026829739776u }, 835 | { 8457595869231446815u, 1719776283537174720u }, 836 | { 10571994836539308519u, 2149720354421468400u }, 837 | { 6607496772837067824u, 1343575221513417750u }, 838 | { 17482743002901110588u, 1679469026891772187u }, 839 | { 17241742735199000331u, 2099336283614715234u }, 840 | { 15387775227926763111u, 1312085177259197021u }, 841 | { 5399660979626290177u, 1640106471573996277u }, 842 | { 11361262242960250625u, 2050133089467495346u }, 843 | { 11712474920277544544u, 1281333180917184591u }, 844 | { 10028907631919542777u, 1601666476146480739u }, 845 | { 7924448521472040567u, 2002083095183100924u }, 846 | { 14176152362774801162u, 1251301934489438077u }, 847 | { 3885132398186337741u, 1564127418111797597u }, 848 | { 9468101516160310080u, 1955159272639746996u }, 849 | { 15140935484454969608u, 1221974545399841872u }, 850 | { 479425281859160394u, 1527468181749802341u }, 851 | { 5210967620751338397u, 1909335227187252926u }, 852 | { 17091912818251750210u, 1193334516992033078u }, 853 | { 12141518985959911954u, 1491668146240041348u }, 854 | { 15176898732449889943u, 1864585182800051685u }, 855 | { 11791404716994875166u, 1165365739250032303u }, 856 | { 10127569877816206054u, 1456707174062540379u }, 857 | { 8047776328842869663u, 1820883967578175474u }, 858 | { 836348374198811271u, 2276104959472719343u }, 859 | { 7440246761515338900u, 1422565599670449589u }, 860 | { 13911994470321561530u, 1778206999588061986u }, 861 | { 8166621051047176104u, 2222758749485077483u }, 862 | { 2798295147690791113u, 1389224218428173427u }, 863 | { 17332926989895652603u, 1736530273035216783u }, 864 | { 17054472718942177850u, 2170662841294020979u }, 865 | { 8353202440125167204u, 1356664275808763112u }, 866 | { 10441503050156459005u, 1695830344760953890u }, 867 | { 3828506775840797949u, 2119787930951192363u }, 868 | { 86973725686804766u, 1324867456844495227u }, 869 | { 13943775212390669669u, 1656084321055619033u }, 870 | { 3594660960206173375u, 2070105401319523792u }, 871 | { 2246663100128858359u, 1293815875824702370u }, 872 | { 12031700912015848757u, 1617269844780877962u }, 873 | { 5816254103165035138u, 2021587305976097453u }, 874 | { 5941001823691840913u, 1263492066235060908u }, 875 | { 7426252279614801142u, 1579365082793826135u }, 876 | { 4671129331091113523u, 1974206353492282669u }, 877 | { 5225298841145639904u, 1233878970932676668u }, 878 | { 6531623551432049880u, 1542348713665845835u }, 879 | { 3552843420862674446u, 1927935892082307294u }, 880 | { 16055585193321335241u, 1204959932551442058u }, 881 | { 10846109454796893243u, 1506199915689302573u }, 882 | { 18169322836923504458u, 1882749894611628216u }, 883 | { 11355826773077190286u, 1176718684132267635u }, 884 | { 9583097447919099954u, 1470898355165334544u }, 885 | { 11978871809898874942u, 1838622943956668180u }, 886 | { 14973589762373593678u, 2298278679945835225u }, 887 | { 2440964573842414192u, 1436424174966147016u }, 888 | { 3051205717303017741u, 1795530218707683770u }, 889 | { 13037379183483547984u, 2244412773384604712u }, 890 | { 8148361989677217490u, 1402757983365377945u }, 891 | { 14797138505523909766u, 1753447479206722431u }, 892 | { 13884737113477499304u, 2191809349008403039u }, 893 | { 15595489723564518921u, 1369880843130251899u }, 894 | { 14882676136028260747u, 1712351053912814874u }, 895 | { 9379973133180550126u, 2140438817391018593u }, 896 | { 17391698254306313589u, 1337774260869386620u }, 897 | { 3292878744173340370u, 1672217826086733276u }, 898 | { 4116098430216675462u, 2090272282608416595u }, 899 | { 266718509671728212u, 1306420176630260372u }, 900 | { 333398137089660265u, 1633025220787825465u }, 901 | { 5028433689789463235u, 2041281525984781831u }, 902 | { 10060300083759496378u, 1275800953740488644u }, 903 | { 12575375104699370472u, 1594751192175610805u }, 904 | { 1884160825592049379u, 1993438990219513507u }, 905 | { 17318501580490888525u, 1245899368887195941u }, 906 | { 7813068920331446945u, 1557374211108994927u }, 907 | { 5154650131986920777u, 1946717763886243659u }, 908 | { 915813323278131534u, 1216698602428902287u }, 909 | { 14979824709379828129u, 1520873253036127858u }, 910 | { 9501408849870009354u, 1901091566295159823u }, 911 | { 12855909558809837702u, 1188182228934474889u }, 912 | { 2234828893230133415u, 1485227786168093612u }, 913 | { 2793536116537666769u, 1856534732710117015u }, 914 | { 8663489100477123587u, 1160334207943823134u }, 915 | { 1605989338741628675u, 1450417759929778918u }, 916 | { 11230858710281811652u, 1813022199912223647u }, 917 | { 9426887369424876662u, 2266277749890279559u }, 918 | { 12809333633531629769u, 1416423593681424724u }, 919 | { 16011667041914537212u, 1770529492101780905u }, 920 | { 6179525747111007803u, 2213161865127226132u }, 921 | { 13085575628799155685u, 1383226165704516332u }, 922 | { 16356969535998944606u, 1729032707130645415u }, 923 | { 15834525901571292854u, 2161290883913306769u }, 924 | { 2979049660840976177u, 1350806802445816731u }, 925 | { 17558870131333383934u, 1688508503057270913u }, 926 | { 8113529608884566205u, 2110635628821588642u }, 927 | { 9682642023980241782u, 1319147268013492901u }, 928 | { 16714988548402690132u, 1648934085016866126u }, 929 | { 11670363648648586857u, 2061167606271082658u }, 930 | { 11905663298832754689u, 1288229753919426661u }, 931 | { 1047021068258779650u, 1610287192399283327u }, 932 | { 15143834390605638274u, 2012858990499104158u }, 933 | { 4853210475701136017u, 1258036869061940099u }, 934 | { 1454827076199032118u, 1572546086327425124u }, 935 | { 1818533845248790147u, 1965682607909281405u }, 936 | { 3442426662494187794u, 1228551629943300878u }, 937 | { 13526405364972510550u, 1535689537429126097u }, 938 | { 3072948650933474476u, 1919611921786407622u }, 939 | { 15755650962115585259u, 1199757451116504763u }, 940 | { 15082877684217093670u, 1499696813895630954u }, 941 | { 9630225068416591280u, 1874621017369538693u }, 942 | { 8324733676974063502u, 1171638135855961683u }, 943 | { 5794231077790191473u, 1464547669819952104u }, 944 | { 7242788847237739342u, 1830684587274940130u }, 945 | { 18276858095901949986u, 2288355734093675162u }, 946 | { 16034722328366106645u, 1430222333808546976u }, 947 | { 1596658836748081690u, 1787777917260683721u }, 948 | { 6607509564362490017u, 2234722396575854651u }, 949 | { 1823850468512862308u, 1396701497859909157u }, 950 | { 6891499104068465790u, 1745876872324886446u }, 951 | { 17837745916940358045u, 2182346090406108057u }, 952 | { 4231062170446641922u, 1363966306503817536u }, 953 | { 5288827713058302403u, 1704957883129771920u }, 954 | { 6611034641322878003u, 2131197353912214900u }, 955 | { 13355268687681574560u, 1331998346195134312u }, 956 | { 16694085859601968200u, 1664997932743917890u }, 957 | { 11644235287647684442u, 2081247415929897363u }, 958 | { 4971804045566108824u, 1300779634956185852u }, 959 | { 6214755056957636030u, 1625974543695232315u }, 960 | { 3156757802769657134u, 2032468179619040394u }, 961 | { 6584659645158423613u, 1270292612261900246u }, 962 | { 17454196593302805324u, 1587865765327375307u }, 963 | { 17206059723201118751u, 1984832206659219134u }, 964 | { 6142101308573311315u, 1240520129162011959u }, 965 | { 3065940617289251240u, 1550650161452514949u }, 966 | { 8444111790038951954u, 1938312701815643686u }, 967 | { 665883850346957067u, 1211445438634777304u }, 968 | { 832354812933696334u, 1514306798293471630u }, 969 | { 10263815553021896226u, 1892883497866839537u }, 970 | { 17944099766707154901u, 1183052186166774710u }, 971 | { 13206752671529167818u, 1478815232708468388u }, 972 | { 16508440839411459773u, 1848519040885585485u }, 973 | { 12623618533845856310u, 1155324400553490928u }, 974 | { 15779523167307320387u, 1444155500691863660u }, 975 | { 1277659885424598868u, 1805194375864829576u }, 976 | { 1597074856780748586u, 2256492969831036970u }, 977 | { 5609857803915355770u, 1410308106144398106u }, 978 | { 16235694291748970521u, 1762885132680497632u }, 979 | { 1847873790976661535u, 2203606415850622041u }, 980 | { 12684136165428883219u, 1377254009906638775u }, 981 | { 11243484188358716120u, 1721567512383298469u }, 982 | { 219297180166231438u, 2151959390479123087u }, 983 | { 7054589765244976505u, 1344974619049451929u }, 984 | { 13429923224983608535u, 1681218273811814911u }, 985 | { 12175718012802122765u, 2101522842264768639u }, 986 | { 14527352785642408584u, 1313451776415480399u }, 987 | { 13547504963625622826u, 1641814720519350499u }, 988 | { 12322695186104640628u, 2052268400649188124u }, 989 | { 16925056528170176201u, 1282667750405742577u }, 990 | { 7321262604930556539u, 1603334688007178222u }, 991 | { 18374950293017971482u, 2004168360008972777u }, 992 | { 4566814905495150320u, 1252605225005607986u }, 993 | { 14931890668723713708u, 1565756531257009982u }, 994 | { 9441491299049866327u, 1957195664071262478u }, 995 | { 1289246043478778550u, 1223247290044539049u }, 996 | { 6223243572775861092u, 1529059112555673811u }, 997 | { 3167368447542438461u, 1911323890694592264u }, 998 | { 1979605279714024038u, 1194577431684120165u }, 999 | { 7086192618069917952u, 1493221789605150206u }, 1000 | { 18081112809442173248u, 1866527237006437757u }, 1001 | { 13606538515115052232u, 1166579523129023598u }, 1002 | { 7784801107039039482u, 1458224403911279498u }, 1003 | { 507629346944023544u, 1822780504889099373u }, 1004 | { 5246222702107417334u, 2278475631111374216u }, 1005 | { 3278889188817135834u, 1424047269444608885u }, 1006 | { 8710297504448807696u, 1780059086805761106u } 1007 | }; 1008 | 1009 | 1010 | 1011 | #define DOUBLE_MANTISSA_BITS 52 1012 | #define DOUBLE_EXPONENT_BITS 11 1013 | #define DOUBLE_BIAS 1023 1014 | 1015 | static inline uint32_t decimalLength17(const uint64_t v) { 1016 | // This is slightly faster than a loop. 1017 | // The average output length is 16.38 digits, so we check high-to-low. 1018 | // Function precondition: v is not an 18, 19, or 20-digit number. 1019 | // (17 digits are sufficient for round-tripping.) 1020 | assert(v < 100000000000000000L); 1021 | if (v >= 10000000000000000L) { return 17; } 1022 | if (v >= 1000000000000000L) { return 16; } 1023 | if (v >= 100000000000000L) { return 15; } 1024 | if (v >= 10000000000000L) { return 14; } 1025 | if (v >= 1000000000000L) { return 13; } 1026 | if (v >= 100000000000L) { return 12; } 1027 | if (v >= 10000000000L) { return 11; } 1028 | if (v >= 1000000000L) { return 10; } 1029 | if (v >= 100000000L) { return 9; } 1030 | if (v >= 10000000L) { return 8; } 1031 | if (v >= 1000000L) { return 7; } 1032 | if (v >= 100000L) { return 6; } 1033 | if (v >= 10000L) { return 5; } 1034 | if (v >= 1000L) { return 4; } 1035 | if (v >= 100L) { return 3; } 1036 | if (v >= 10L) { return 2; } 1037 | return 1; 1038 | } 1039 | 1040 | // A floating decimal representing m * 10^e. 1041 | typedef struct floating_decimal_64 { 1042 | uint64_t mantissa; 1043 | // Decimal exponent's range is -324 to 308 1044 | // inclusive, and can fit in a short if needed. 1045 | int32_t exponent; 1046 | } floating_decimal_64; 1047 | 1048 | static inline floating_decimal_64 d2d(const uint64_t ieeeMantissa, 1049 | const uint32_t ieeeExponent) 1050 | { 1051 | int32_t e2; 1052 | uint64_t m2; 1053 | if (ieeeExponent == 0) { 1054 | // We subtract 2 so that the bounds computation has 2 additional bits. 1055 | e2 = 1 - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS - 2; 1056 | m2 = ieeeMantissa; 1057 | } else { 1058 | e2 = (int32_t) ieeeExponent - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS - 2; 1059 | m2 = (1ull << DOUBLE_MANTISSA_BITS) | ieeeMantissa; 1060 | } 1061 | const bool even = (m2 & 1) == 0; 1062 | const bool acceptBounds = even; 1063 | 1064 | // Step 2: Determine the interval of valid decimal representations. 1065 | const uint64_t mv = 4 * m2; 1066 | // Implicit bool -> int conversion. True is 1, false is 0. 1067 | const uint32_t mmShift = ieeeMantissa != 0 || ieeeExponent <= 1; 1068 | // We would compute mp and mm like this: 1069 | // uint64_t mp = 4 * m2 + 2; 1070 | // uint64_t mm = mv - 1 - mmShift; 1071 | 1072 | // Step 3: Convert to a decimal power base using 128-bit arithmetic. 1073 | uint64_t vr, vp, vm; 1074 | int32_t e10; 1075 | bool vmIsTrailingZeros = false; 1076 | bool vrIsTrailingZeros = false; 1077 | if (e2 >= 0) { 1078 | // I tried special-casing q == 0, but there was no effect on 1079 | // performance. 1080 | // This expression is slightly faster than max(0, log10Pow2(e2) - 1). 1081 | const uint32_t q = log10Pow2(e2) - (e2 > 3); 1082 | e10 = (int32_t) q; 1083 | const int32_t k = DOUBLE_POW5_INV_BITCOUNT + pow5bits((int32_t) q) - 1; 1084 | const int32_t i = -e2 + (int32_t) q + k; 1085 | vr = mulShiftAll64(m2, DOUBLE_POW5_INV_SPLIT[q], i, &vp, &vm, mmShift); 1086 | if (q <= 21) { 1087 | // This should use q <= 22, but I think 21 is also safe. Smaller 1088 | // values may still be safe, but it's more difficult to reason 1089 | // about them. Only one of mp, mv, and mm can be a multiple of 5, 1090 | // if any. 1091 | const uint32_t mvMod5 = ((uint32_t) mv) - 5 * ((uint32_t) div5(mv)); 1092 | if (mvMod5 == 0) { 1093 | vrIsTrailingZeros = multipleOfPowerOf5(mv, q); 1094 | } else if (acceptBounds) { 1095 | // Same as min(e2 + (~mm & 1), pow5Factor(mm)) >= q 1096 | // <=> e2 + (~mm & 1) >= q && pow5Factor(mm) >= q 1097 | // <=> true && pow5Factor(mm) >= q, since e2 >= q. 1098 | vmIsTrailingZeros = multipleOfPowerOf5(mv - 1 - mmShift, q); 1099 | } else { 1100 | // Same as min(e2 + 1, pow5Factor(mp)) >= q. 1101 | vp -= multipleOfPowerOf5(mv + 2, q); 1102 | } 1103 | } 1104 | } else { 1105 | // This expression is slightly faster than max(0, log10Pow5(-e2) - 1). 1106 | const uint32_t q = log10Pow5(-e2) - (-e2 > 1); 1107 | e10 = (int32_t) q + e2; 1108 | const int32_t i = -e2 - (int32_t) q; 1109 | const int32_t k = pow5bits(i) - DOUBLE_POW5_BITCOUNT; 1110 | const int32_t j = (int32_t) q - k; 1111 | vr = mulShiftAll64(m2, DOUBLE_POW5_SPLIT[i], j, &vp, &vm, mmShift); 1112 | if (q <= 1) { 1113 | // {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q 1114 | // trailing 0 bits. mv = 4 * m2, so it always has at least two 1115 | // trailing 0 bits. 1116 | vrIsTrailingZeros = true; 1117 | if (acceptBounds) { 1118 | // mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff 1119 | // mmShift == 1. 1120 | vmIsTrailingZeros = mmShift == 1; 1121 | } else { 1122 | // mp = mv + 2, so it always has at least one trailing 0 bit. 1123 | --vp; 1124 | } 1125 | } else if (q < 63) { // TODO(ulfjack): Use a tighter bound here. 1126 | // We want to know if the full product has at least q trailing 1127 | // zeros. 1128 | // We need to compute min(p2(mv), p5(mv) - e2) >= q 1129 | // <=> p2(mv) >= q && p5(mv) - e2 >= q 1130 | // <=> p2(mv) >= q (because -e2 >= q) 1131 | vrIsTrailingZeros = multipleOfPowerOf2(mv, q); 1132 | } 1133 | } 1134 | 1135 | // Step 4: Find the shortest decimal representation in the interval of 1136 | // valid representations. 1137 | int32_t removed = 0; 1138 | uint8_t lastRemovedDigit = 0; 1139 | uint64_t output; 1140 | // On average, we remove ~2 digits. 1141 | if (vmIsTrailingZeros || vrIsTrailingZeros) { 1142 | // General case, which happens rarely (~0.7%). 1143 | for (;;) { 1144 | const uint64_t vpDiv10 = div10(vp); 1145 | const uint64_t vmDiv10 = div10(vm); 1146 | if (vpDiv10 <= vmDiv10) { 1147 | break; 1148 | } 1149 | const uint32_t vmMod10 = ((uint32_t) vm) - 10 * 1150 | ((uint32_t) vmDiv10); 1151 | const uint64_t vrDiv10 = div10(vr); 1152 | const uint32_t vrMod10 = ((uint32_t) vr) - 10 * 1153 | ((uint32_t) vrDiv10); 1154 | vmIsTrailingZeros &= vmMod10 == 0; 1155 | vrIsTrailingZeros &= lastRemovedDigit == 0; 1156 | lastRemovedDigit = (uint8_t) vrMod10; 1157 | vr = vrDiv10; 1158 | vp = vpDiv10; 1159 | vm = vmDiv10; 1160 | ++removed; 1161 | } 1162 | if (vmIsTrailingZeros) { 1163 | for (;;) { 1164 | const uint64_t vmDiv10 = div10(vm); 1165 | const uint32_t vmMod10 = ((uint32_t) vm) - 10 * 1166 | ((uint32_t) vmDiv10); 1167 | if (vmMod10 != 0) { 1168 | break; 1169 | } 1170 | const uint64_t vpDiv10 = div10(vp); 1171 | const uint64_t vrDiv10 = div10(vr); 1172 | const uint32_t vrMod10 = ((uint32_t) vr) - 10 * 1173 | ((uint32_t) vrDiv10); 1174 | vrIsTrailingZeros &= lastRemovedDigit == 0; 1175 | lastRemovedDigit = (uint8_t) vrMod10; 1176 | vr = vrDiv10; 1177 | vp = vpDiv10; 1178 | vm = vmDiv10; 1179 | ++removed; 1180 | } 1181 | } 1182 | if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0) { 1183 | // Round even if the exact number is .....50..0. 1184 | lastRemovedDigit = 4; 1185 | } 1186 | // We need to take vr + 1 if vr is outside bounds or we need to round 1187 | // up. 1188 | output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || 1189 | lastRemovedDigit >= 5); 1190 | } else { 1191 | // Specialized for the common case (~99.3%). Percentages below are 1192 | // relative to this. 1193 | bool roundUp = false; 1194 | const uint64_t vpDiv100 = div100(vp); 1195 | const uint64_t vmDiv100 = div100(vm); 1196 | if (vpDiv100 > vmDiv100) { // Opt: remove two digits at a time (~86.2%). 1197 | const uint64_t vrDiv100 = div100(vr); 1198 | const uint32_t vrMod100 = ((uint32_t) vr) - 100 * 1199 | ((uint32_t) vrDiv100); 1200 | roundUp = vrMod100 >= 50; 1201 | vr = vrDiv100; 1202 | vp = vpDiv100; 1203 | vm = vmDiv100; 1204 | removed += 2; 1205 | } 1206 | // Loop iterations below (approximately), without optimization above: 1207 | // 0: 0.03%, 1: 13.8%, 2: 70.6%, 3: 14.0%, 4: 1.40%, 5: 0.14%, 6+: 0.02% 1208 | // Loop iterations below (approximately), with optimization above: 1209 | // 0: 70.6%, 1: 27.8%, 2: 1.40%, 3: 0.14%, 4+: 0.02% 1210 | for (;;) { 1211 | const uint64_t vpDiv10 = div10(vp); 1212 | const uint64_t vmDiv10 = div10(vm); 1213 | if (vpDiv10 <= vmDiv10) { 1214 | break; 1215 | } 1216 | const uint64_t vrDiv10 = div10(vr); 1217 | const uint32_t vrMod10 = ((uint32_t) vr) - 10 * 1218 | ((uint32_t) vrDiv10); 1219 | roundUp = vrMod10 >= 5; 1220 | vr = vrDiv10; 1221 | vp = vpDiv10; 1222 | vm = vmDiv10; 1223 | ++removed; 1224 | } 1225 | // We need to take vr + 1 if vr is outside bounds or we need to round 1226 | // up. 1227 | output = vr + (vr == vm || roundUp); 1228 | } 1229 | const int32_t exp = e10 + removed; 1230 | 1231 | floating_decimal_64 fd; 1232 | fd.exponent = exp; 1233 | fd.mantissa = output; 1234 | return fd; 1235 | } 1236 | 1237 | static inline int to_chars64(const floating_decimal_64 v, const bool sign, 1238 | char* const result) 1239 | { 1240 | // Step 5: Print the decimal representation. 1241 | int index = 0; 1242 | if (sign) { 1243 | result[index++] = '-'; 1244 | } 1245 | 1246 | uint64_t output = v.mantissa; 1247 | const uint32_t olength = decimalLength17(output); 1248 | 1249 | // Print the decimal digits. 1250 | // The following code is equivalent to: 1251 | // for (uint32_t i = 0; i < olength - 1; ++i) { 1252 | // const uint32_t c = output % 10; output /= 10; 1253 | // result[index + olength - i] = (char) ('0' + c); 1254 | // } 1255 | // result[index] = '0' + output % 10; 1256 | 1257 | uint32_t i = 0; 1258 | // We prefer 32-bit operations, even on 64-bit platforms. 1259 | // We have at most 17 digits, and uint32_t can store 9 digits. 1260 | // If output doesn't fit into uint32_t, we cut off 8 digits, 1261 | // so the rest will fit into uint32_t. 1262 | if ((output >> 32) != 0) { 1263 | // Expensive 64-bit division. 1264 | const uint64_t q = div1e8(output); 1265 | uint32_t output2 = ((uint32_t) output) - 100000000 * ((uint32_t) q); 1266 | output = q; 1267 | 1268 | const uint32_t c = output2 % 10000; 1269 | output2 /= 10000; 1270 | const uint32_t d = output2 % 10000; 1271 | const uint32_t c0 = (c % 100) << 1; 1272 | const uint32_t c1 = (c / 100) << 1; 1273 | const uint32_t d0 = (d % 100) << 1; 1274 | const uint32_t d1 = (d / 100) << 1; 1275 | memcpy(result + index + olength - 1, DIGIT_TABLE + c0, 2); 1276 | memcpy(result + index + olength - 3, DIGIT_TABLE + c1, 2); 1277 | memcpy(result + index + olength - 5, DIGIT_TABLE + d0, 2); 1278 | memcpy(result + index + olength - 7, DIGIT_TABLE + d1, 2); 1279 | i += 8; 1280 | } 1281 | uint32_t output2 = (uint32_t) output; 1282 | while (output2 >= 10000) { 1283 | #ifdef __clang__ // https://bugs.llvm.org/show_bug.cgi?id=38217 1284 | const uint32_t c = output2 - 10000 * (output2 / 10000); 1285 | #else 1286 | const uint32_t c = output2 % 10000; 1287 | #endif 1288 | output2 /= 10000; 1289 | const uint32_t c0 = (c % 100) << 1; 1290 | const uint32_t c1 = (c / 100) << 1; 1291 | memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2); 1292 | memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2); 1293 | i += 4; 1294 | } 1295 | if (output2 >= 100) { 1296 | const uint32_t c = (output2 % 100) << 1; 1297 | output2 /= 100; 1298 | memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2); 1299 | i += 2; 1300 | } 1301 | if (output2 >= 10) { 1302 | const uint32_t c = output2 << 1; 1303 | // We can't use memcpy here: the decimal dot goes between these two 1304 | // digits. 1305 | result[index + olength - i] = DIGIT_TABLE[c + 1]; 1306 | result[index] = DIGIT_TABLE[c]; 1307 | } else { 1308 | result[index] = (char) ('0' + output2); 1309 | } 1310 | 1311 | // Print decimal point if needed. 1312 | if (olength > 1) { 1313 | result[index + 1] = '.'; 1314 | index += olength + 1; 1315 | } else { 1316 | ++index; 1317 | } 1318 | 1319 | // Print the exponent. 1320 | result[index++] = 'E'; 1321 | int32_t exp = v.exponent + (int32_t) olength - 1; 1322 | if (exp < 0) { 1323 | result[index++] = '-'; 1324 | exp = -exp; 1325 | } 1326 | 1327 | if (exp >= 100) { 1328 | const int32_t c = exp % 10; 1329 | memcpy(result + index, DIGIT_TABLE + 2 * (exp / 10), 2); 1330 | result[index + 2] = (char) ('0' + c); 1331 | index += 3; 1332 | } else if (exp >= 10) { 1333 | memcpy(result + index, DIGIT_TABLE + 2 * exp, 2); 1334 | index += 2; 1335 | } else { 1336 | result[index++] = (char) ('0' + exp); 1337 | } 1338 | 1339 | return index; 1340 | } 1341 | 1342 | static inline bool d2d_small_int(const uint64_t ieeeMantissa, 1343 | const uint32_t ieeeExponent, floating_decimal_64* const v) 1344 | { 1345 | const uint64_t m2 = (1ull << DOUBLE_MANTISSA_BITS) | ieeeMantissa; 1346 | const int32_t e2 = (int32_t) ieeeExponent - DOUBLE_BIAS - 1347 | DOUBLE_MANTISSA_BITS; 1348 | 1349 | if (e2 > 0) { 1350 | // f = m2 * 2^e2 >= 2^53 is an integer. 1351 | // Ignore this case for now. 1352 | return false; 1353 | } 1354 | 1355 | if (e2 < -52) { 1356 | // f < 1. 1357 | return false; 1358 | } 1359 | 1360 | // Since 2^52 <= m2 < 2^53 and 0 <= -e2 <= 52: 1 <= f = m2 / 2^-e2 < 2^53. 1361 | // Test if the lower -e2 bits of the significand are 0, i.e. whether the 1362 | // fraction is 0. 1363 | const uint64_t mask = (1ull << -e2) - 1; 1364 | const uint64_t fraction = m2 & mask; 1365 | if (fraction != 0) { 1366 | return false; 1367 | } 1368 | 1369 | // f is an integer in the range [1, 2^53). 1370 | // Note: mantissa might contain trailing (decimal) 0's. 1371 | // Note: since 2^53 < 10^16, there is no need to adjust decimalLength17(). 1372 | v->mantissa = m2 >> -e2; 1373 | v->exponent = 0; 1374 | return true; 1375 | } 1376 | 1377 | static int d2s_buffered_n(double f, char* result) { 1378 | // Step 1: Decode the floating-point number, and unify normalized and 1379 | // subnormal cases. 1380 | const uint64_t bits = double_to_bits(f); 1381 | 1382 | // Decode bits into sign, mantissa, and exponent. 1383 | const bool ieeeSign = ((bits >> (DOUBLE_MANTISSA_BITS + 1384 | DOUBLE_EXPONENT_BITS)) & 1) != 0; 1385 | const uint64_t ieeeMantissa = bits & ((1ull << DOUBLE_MANTISSA_BITS) - 1); 1386 | const uint32_t ieeeExponent = (uint32_t) ((bits >> DOUBLE_MANTISSA_BITS) & 1387 | ((1u << DOUBLE_EXPONENT_BITS) - 1)); 1388 | // Case distinction; exit early for the easy cases. 1389 | if (ieeeExponent == ((1u << DOUBLE_EXPONENT_BITS) - 1u) || 1390 | (ieeeExponent == 0 && ieeeMantissa == 0)) 1391 | { 1392 | return copy_special_str(result, ieeeSign, ieeeExponent, ieeeMantissa); 1393 | } 1394 | 1395 | floating_decimal_64 v; 1396 | const bool isSmallInt = d2d_small_int(ieeeMantissa, ieeeExponent, &v); 1397 | if (isSmallInt) { 1398 | // For small integers in the range [1, 2^53), v.mantissa might contain 1399 | // trailing (decimal) zeros. 1400 | // For scientific notation we need to move these zeros into the 1401 | // exponent. 1402 | // (This is not needed for fixed-point notation, so it might be 1403 | // beneficial to trim 1404 | // trailing zeros in to_chars only if needed - once fixed-point 1405 | // notation output is implemented.) 1406 | for (;;) { 1407 | const uint64_t q = div10(v.mantissa); 1408 | const uint32_t r = ((uint32_t) v.mantissa) - 10 * ((uint32_t) q); 1409 | if (r != 0) { 1410 | break; 1411 | } 1412 | v.mantissa = q; 1413 | ++v.exponent; 1414 | } 1415 | } else { 1416 | v = d2d(ieeeMantissa, ieeeExponent); 1417 | } 1418 | 1419 | return to_chars64(v, ieeeSign, result); 1420 | } 1421 | 1422 | static void d2s_buffered(double f, char* result) { 1423 | (void)umul128; (void)shiftright128; (void)mod1e9; 1424 | const int index = d2s_buffered_n(f, result); 1425 | 1426 | // Terminate the string. 1427 | result[index] = '\0'; 1428 | } 1429 | 1430 | // Returns the number of decimal digits in v, which must not contain more than 1431 | // 9 digits. 1432 | static inline uint32_t decimalLength9(const uint32_t v) { 1433 | // Function precondition: v is not a 10-digit number. 1434 | // (f2s: 9 digits are sufficient for round-tripping.) 1435 | // (d2fixed: We print 9-digit blocks.) 1436 | assert(v < 1000000000); 1437 | if (v >= 100000000) { return 9; } 1438 | if (v >= 10000000) { return 8; } 1439 | if (v >= 1000000) { return 7; } 1440 | if (v >= 100000) { return 6; } 1441 | if (v >= 10000) { return 5; } 1442 | if (v >= 1000) { return 4; } 1443 | if (v >= 100) { return 3; } 1444 | if (v >= 10) { return 2; } 1445 | return 1; 1446 | } 1447 | 1448 | static inline uint32_t float_to_bits(const float f) { 1449 | uint32_t bits = 0; 1450 | memcpy(&bits, &f, sizeof(float)); 1451 | return bits; 1452 | } 1453 | 1454 | #define DOUBLE_POW5_INV_BITCOUNT 125 1455 | #define DOUBLE_POW5_BITCOUNT 125 1456 | #define DOUBLE_POW5_INV_TABLE_SIZE 342 1457 | #define DOUBLE_POW5_TABLE_SIZE 326 1458 | #define FLOAT_POW5_INV_BITCOUNT (DOUBLE_POW5_INV_BITCOUNT - 64) 1459 | #define FLOAT_POW5_BITCOUNT (DOUBLE_POW5_BITCOUNT - 64) 1460 | 1461 | static inline uint32_t pow5factor_32(uint32_t value) { 1462 | uint32_t count = 0; 1463 | for (;;) { 1464 | assert(value != 0); 1465 | const uint32_t q = value / 5; 1466 | const uint32_t r = value % 5; 1467 | if (r != 0) { 1468 | break; 1469 | } 1470 | value = q; 1471 | ++count; 1472 | } 1473 | return count; 1474 | } 1475 | 1476 | // Returns true if value is divisible by 5^p. 1477 | static inline bool multipleOfPowerOf5_32(const uint32_t value, 1478 | const uint32_t p) 1479 | { 1480 | return pow5factor_32(value) >= p; 1481 | } 1482 | 1483 | // Returns true if value is divisible by 2^p. 1484 | static inline bool multipleOfPowerOf2_32(const uint32_t value, 1485 | const uint32_t p) 1486 | { 1487 | // __builtin_ctz doesn't appear to be faster here. 1488 | return (value & ((1u << p) - 1)) == 0; 1489 | } 1490 | 1491 | // It seems to be slightly faster to avoid uint128_t here, although the 1492 | // generated code for uint128_t looks slightly nicer. 1493 | static inline uint32_t mulShift32(const uint32_t m, const uint64_t factor, 1494 | const int32_t shift) 1495 | { 1496 | assert(shift > 32); 1497 | 1498 | // The casts here help MSVC to avoid calls to the __allmul library 1499 | // function. 1500 | const uint32_t factorLo = (uint32_t)(factor); 1501 | const uint32_t factorHi = (uint32_t)(factor >> 32); 1502 | const uint64_t bits0 = (uint64_t)m * factorLo; 1503 | const uint64_t bits1 = (uint64_t)m * factorHi; 1504 | const uint64_t sum = (bits0 >> 32) + bits1; 1505 | const uint64_t shiftedSum = sum >> (shift - 32); 1506 | assert(shiftedSum <= UINT32_MAX); 1507 | return (uint32_t) shiftedSum; 1508 | } 1509 | 1510 | static inline uint32_t mulPow5InvDivPow2(const uint32_t m, const uint32_t q, 1511 | const int32_t j) 1512 | { 1513 | return mulShift32(m, DOUBLE_POW5_INV_SPLIT[q][1] + 1, j); 1514 | } 1515 | 1516 | static inline uint32_t mulPow5divPow2(const uint32_t m, const uint32_t i, 1517 | const int32_t j) 1518 | { 1519 | return mulShift32(m, DOUBLE_POW5_SPLIT[i][1], j); 1520 | } 1521 | 1522 | #define FLOAT_MANTISSA_BITS 23 1523 | #define FLOAT_EXPONENT_BITS 8 1524 | #define FLOAT_BIAS 127 1525 | 1526 | // A floating decimal representing m * 10^e. 1527 | typedef struct floating_decimal_32 { 1528 | uint32_t mantissa; 1529 | // Decimal exponent's range is -45 to 38 1530 | // inclusive, and can fit in a short if needed. 1531 | int32_t exponent; 1532 | } floating_decimal_32; 1533 | 1534 | static inline floating_decimal_32 f2d(const uint32_t ieeeMantissa, 1535 | const uint32_t ieeeExponent) 1536 | { 1537 | int32_t e2; 1538 | uint32_t m2; 1539 | if (ieeeExponent == 0) { 1540 | // We subtract 2 so that the bounds computation has 2 additional bits. 1541 | e2 = 1 - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2; 1542 | m2 = ieeeMantissa; 1543 | } else { 1544 | e2 = (int32_t) ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2; 1545 | m2 = (1u << FLOAT_MANTISSA_BITS) | ieeeMantissa; 1546 | } 1547 | const bool even = (m2 & 1) == 0; 1548 | const bool acceptBounds = even; 1549 | 1550 | // Step 2: Determine the interval of valid decimal representations. 1551 | const uint32_t mv = 4 * m2; 1552 | const uint32_t mp = 4 * m2 + 2; 1553 | // Implicit bool -> int conversion. True is 1, false is 0. 1554 | const uint32_t mmShift = ieeeMantissa != 0 || ieeeExponent <= 1; 1555 | const uint32_t mm = 4 * m2 - 1 - mmShift; 1556 | 1557 | // Step 3: Convert to a decimal power base using 64-bit arithmetic. 1558 | uint32_t vr, vp, vm; 1559 | int32_t e10; 1560 | bool vmIsTrailingZeros = false; 1561 | bool vrIsTrailingZeros = false; 1562 | uint8_t lastRemovedDigit = 0; 1563 | if (e2 >= 0) { 1564 | const uint32_t q = log10Pow2(e2); 1565 | e10 = (int32_t) q; 1566 | const int32_t k = FLOAT_POW5_INV_BITCOUNT + pow5bits((int32_t) q) - 1; 1567 | const int32_t i = -e2 + (int32_t) q + k; 1568 | vr = mulPow5InvDivPow2(mv, q, i); 1569 | vp = mulPow5InvDivPow2(mp, q, i); 1570 | vm = mulPow5InvDivPow2(mm, q, i); 1571 | if (q != 0 && (vp - 1) / 10 <= vm / 10) { 1572 | // We need to know one removed digit even if we are not going to 1573 | // loop below. We could use q = X - 1 above, except that would 1574 | // require 33 bits for the result, and we've found that 1575 | // 32-bit arithmetic is faster even on 64-bit machines. 1576 | const int32_t l = FLOAT_POW5_INV_BITCOUNT + 1577 | pow5bits((int32_t)(q - 1)) - 1; 1578 | lastRemovedDigit = (uint8_t) (mulPow5InvDivPow2(mv, q - 1, -e2 + 1579 | (int32_t) q - 1 + l) % 10); 1580 | } 1581 | if (q <= 9) { 1582 | // The largest power of 5 that fits in 24 bits is 5^10, but q <= 9 1583 | // seems to be safe as well. 1584 | // Only one of mp, mv, and mm can be a multiple of 5, if any. 1585 | if (mv % 5 == 0) { 1586 | vrIsTrailingZeros = multipleOfPowerOf5_32(mv, q); 1587 | } else if (acceptBounds) { 1588 | vmIsTrailingZeros = multipleOfPowerOf5_32(mm, q); 1589 | } else { 1590 | vp -= multipleOfPowerOf5_32(mp, q); 1591 | } 1592 | } 1593 | } else { 1594 | const uint32_t q = log10Pow5(-e2); 1595 | e10 = (int32_t) q + e2; 1596 | const int32_t i = -e2 - (int32_t) q; 1597 | const int32_t k = pow5bits(i) - FLOAT_POW5_BITCOUNT; 1598 | int32_t j = (int32_t) q - k; 1599 | vr = mulPow5divPow2(mv, (uint32_t) i, j); 1600 | vp = mulPow5divPow2(mp, (uint32_t) i, j); 1601 | vm = mulPow5divPow2(mm, (uint32_t) i, j); 1602 | if (q != 0 && (vp - 1) / 10 <= vm / 10) { 1603 | j = (int32_t) q - 1 - (pow5bits(i + 1) - FLOAT_POW5_BITCOUNT); 1604 | lastRemovedDigit = (uint8_t) (mulPow5divPow2(mv, 1605 | (uint32_t) (i + 1), j) % 10); 1606 | } 1607 | if (q <= 1) { 1608 | // {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q 1609 | // trailing 0 bits. 1610 | // mv = 4 * m2, so it always has at least two trailing 0 bits. 1611 | vrIsTrailingZeros = true; 1612 | if (acceptBounds) { 1613 | // mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff 1614 | // mmShift == 1. 1615 | vmIsTrailingZeros = mmShift == 1; 1616 | } else { 1617 | // mp = mv + 2, so it always has at least one trailing 0 bit. 1618 | --vp; 1619 | } 1620 | } else if (q < 31) { // TODO(ulfjack): Use a tighter bound here. 1621 | vrIsTrailingZeros = multipleOfPowerOf2_32(mv, q - 1); 1622 | } 1623 | } 1624 | 1625 | // Step 4: Find the shortest decimal representation in the interval of 1626 | // valid representations. 1627 | int32_t removed = 0; 1628 | uint32_t output; 1629 | if (vmIsTrailingZeros || vrIsTrailingZeros) { 1630 | // General case, which happens rarely (~4.0%). 1631 | while (vp / 10 > vm / 10) { 1632 | #ifdef __clang__ // https://bugs.llvm.org/show_bug.cgi?id=23106 1633 | // The compiler does not realize that vm % 10 can be computed from 1634 | // vm / 10 as vm - (vm / 10) * 10. 1635 | vmIsTrailingZeros &= vm - (vm / 10) * 10 == 0; 1636 | #else 1637 | vmIsTrailingZeros &= vm % 10 == 0; 1638 | #endif 1639 | vrIsTrailingZeros &= lastRemovedDigit == 0; 1640 | lastRemovedDigit = (uint8_t) (vr % 10); 1641 | vr /= 10; 1642 | vp /= 10; 1643 | vm /= 10; 1644 | ++removed; 1645 | } 1646 | if (vmIsTrailingZeros) { 1647 | while (vm % 10 == 0) { 1648 | vrIsTrailingZeros &= lastRemovedDigit == 0; 1649 | lastRemovedDigit = (uint8_t) (vr % 10); 1650 | vr /= 10; 1651 | vp /= 10; 1652 | vm /= 10; 1653 | ++removed; 1654 | } 1655 | } 1656 | if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0) { 1657 | // Round even if the exact number is .....50..0. 1658 | lastRemovedDigit = 4; 1659 | } 1660 | // We need to take vr + 1 if vr is outside bounds or we need to round 1661 | // up. 1662 | output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || 1663 | lastRemovedDigit >= 5); 1664 | } else { 1665 | // Specialized for the common case (~96.0%). Percentages below are 1666 | // relative to this. 1667 | // Loop iterations below (approximately): 1668 | // 0: 13.6%, 1: 70.7%, 2: 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01% 1669 | while (vp / 10 > vm / 10) { 1670 | lastRemovedDigit = (uint8_t) (vr % 10); 1671 | vr /= 10; 1672 | vp /= 10; 1673 | vm /= 10; 1674 | ++removed; 1675 | } 1676 | // We need to take vr + 1 if vr is outside bounds or we need to round 1677 | // up. 1678 | output = vr + (vr == vm || lastRemovedDigit >= 5); 1679 | } 1680 | const int32_t exp = e10 + removed; 1681 | 1682 | floating_decimal_32 fd; 1683 | fd.exponent = exp; 1684 | fd.mantissa = output; 1685 | return fd; 1686 | } 1687 | 1688 | static inline int to_chars(const floating_decimal_32 v, const bool sign, 1689 | char* const result) 1690 | { 1691 | // Step 5: Print the decimal representation. 1692 | int index = 0; 1693 | if (sign) { 1694 | result[index++] = '-'; 1695 | } 1696 | 1697 | uint32_t output = v.mantissa; 1698 | const uint32_t olength = decimalLength9(output); 1699 | 1700 | 1701 | // Print the decimal digits. 1702 | // The following code is equivalent to: 1703 | // for (uint32_t i = 0; i < olength - 1; ++i) { 1704 | // const uint32_t c = output % 10; output /= 10; 1705 | // result[index + olength - i] = (char) ('0' + c); 1706 | // } 1707 | // result[index] = '0' + output % 10; 1708 | uint32_t i = 0; 1709 | while (output >= 10000) { 1710 | #ifdef __clang__ // https://bugs.llvm.org/show_bug.cgi?id=38217 1711 | const uint32_t c = output - 10000 * (output / 10000); 1712 | #else 1713 | const uint32_t c = output % 10000; 1714 | #endif 1715 | output /= 10000; 1716 | const uint32_t c0 = (c % 100) << 1; 1717 | const uint32_t c1 = (c / 100) << 1; 1718 | memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2); 1719 | memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2); 1720 | i += 4; 1721 | } 1722 | if (output >= 100) { 1723 | const uint32_t c = (output % 100) << 1; 1724 | output /= 100; 1725 | memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2); 1726 | i += 2; 1727 | } 1728 | if (output >= 10) { 1729 | const uint32_t c = output << 1; 1730 | // We can't use memcpy here: the decimal dot goes between these two 1731 | // digits. 1732 | result[index + olength - i] = DIGIT_TABLE[c + 1]; 1733 | result[index] = DIGIT_TABLE[c]; 1734 | } else { 1735 | result[index] = (char) ('0' + output); 1736 | } 1737 | 1738 | // Print decimal point if needed. 1739 | if (olength > 1) { 1740 | result[index + 1] = '.'; 1741 | index += olength + 1; 1742 | } else { 1743 | ++index; 1744 | } 1745 | 1746 | // Print the exponent. 1747 | result[index++] = 'E'; 1748 | int32_t exp = v.exponent + (int32_t) olength - 1; 1749 | if (exp < 0) { 1750 | result[index++] = '-'; 1751 | exp = -exp; 1752 | } 1753 | 1754 | if (exp >= 10) { 1755 | memcpy(result + index, DIGIT_TABLE + 2 * exp, 2); 1756 | index += 2; 1757 | } else { 1758 | result[index++] = (char) ('0' + exp); 1759 | } 1760 | 1761 | return index; 1762 | } 1763 | 1764 | static int f2s_buffered_n(float f, char* result) { 1765 | // Step 1: Decode the floating-point number, and unify normalized and 1766 | // subnormal cases. 1767 | const uint32_t bits = float_to_bits(f); 1768 | 1769 | 1770 | // Decode bits into sign, mantissa, and exponent. 1771 | const bool ieeeSign = ((bits >> (FLOAT_MANTISSA_BITS + 1772 | FLOAT_EXPONENT_BITS)) & 1) != 0; 1773 | const uint32_t ieeeMantissa = bits & ((1u << FLOAT_MANTISSA_BITS) - 1); 1774 | const uint32_t ieeeExponent = (bits >> FLOAT_MANTISSA_BITS) & 1775 | ((1u << FLOAT_EXPONENT_BITS) - 1); 1776 | 1777 | // Case distinction; exit early for the easy cases. 1778 | if (ieeeExponent == ((1u << FLOAT_EXPONENT_BITS) - 1u) || 1779 | (ieeeExponent == 0 && ieeeMantissa == 0)) 1780 | { 1781 | return copy_special_str(result, ieeeSign, ieeeExponent, ieeeMantissa); 1782 | } 1783 | 1784 | const floating_decimal_32 v = f2d(ieeeMantissa, ieeeExponent); 1785 | return to_chars(v, ieeeSign, result); 1786 | } 1787 | 1788 | static void f2s_buffered(float f, char* result) { 1789 | const int index = f2s_buffered_n(f, result); 1790 | 1791 | // Terminate the string. 1792 | result[index] = '\0'; 1793 | } 1794 | 1795 | enum RyuStatus { 1796 | RYU_SUCCESS, 1797 | RYU_INPUT_TOO_SHORT, 1798 | RYU_INPUT_TOO_LONG, 1799 | RYU_MALFORMED_INPUT 1800 | }; 1801 | 1802 | // Returns e == 0 ? 1 : [log_2(5^e)]; requires 0 <= e <= 3528. 1803 | static inline int32_t log2pow5(const int32_t e) { 1804 | // This approximation works up to the point that the multiplication 1805 | // overflows at e = 3529. 1806 | // If the multiplication were done in 64 bits, it would fail at 5^4004 1807 | // which is just greater than 2^9297. 1808 | assert(e >= 0); 1809 | assert(e <= 3528); 1810 | return (int32_t) ((((uint32_t) e) * 1217359) >> 19); 1811 | } 1812 | 1813 | // Returns e == 0 ? 1 : ceil(log_2(5^e)); requires 0 <= e <= 3528. 1814 | static inline int32_t ceil_log2pow5(const int32_t e) { 1815 | return log2pow5(e) + 1; 1816 | } 1817 | 1818 | // These tables are generated by PrintDoubleLookupTable. 1819 | #define DOUBLE_POW5_INV_BITCOUNT 125 1820 | #define DOUBLE_POW5_BITCOUNT 125 1821 | 1822 | #define DOUBLE_POW5_INV_TABLE_SIZE 342 1823 | #define DOUBLE_POW5_TABLE_SIZE 326 1824 | 1825 | #define DOUBLE_MANTISSA_BITS 52 1826 | #define DOUBLE_EXPONENT_BITS 11 1827 | #define DOUBLE_EXPONENT_BIAS 1023 1828 | 1829 | static inline uint32_t floor_log2(const uint64_t value) { 1830 | return 63 - __builtin_clzll(value); 1831 | } 1832 | 1833 | // The max function is already defined on Windows. 1834 | static inline int32_t max32(int32_t a, int32_t b) { 1835 | return a < b ? b : a; 1836 | } 1837 | 1838 | static inline double int64Bits2Double(uint64_t bits) { 1839 | double f; 1840 | memcpy(&f, &bits, sizeof(double)); 1841 | return f; 1842 | } 1843 | 1844 | static enum RyuStatus s2d_n(const char * buffer, const int len, double * result) 1845 | { 1846 | if (len == 0) { 1847 | return RYU_INPUT_TOO_SHORT; 1848 | } 1849 | int m10digits = 0; 1850 | int e10digits = 0; 1851 | int dotIndex = len; 1852 | int eIndex = len; 1853 | uint64_t m10 = 0; 1854 | int32_t e10 = 0; 1855 | bool signedM = false; 1856 | bool signedE = false; 1857 | int i = 0; 1858 | if (buffer[i] == '-') { 1859 | signedM = true; 1860 | i++; 1861 | } 1862 | for (; i < len; i++) { 1863 | char c = buffer[i]; 1864 | if (c == '.') { 1865 | if (dotIndex != len) { 1866 | return RYU_MALFORMED_INPUT; 1867 | } 1868 | dotIndex = i; 1869 | continue; 1870 | } 1871 | if ((c < '0') || (c > '9')) { 1872 | break; 1873 | } 1874 | if (m10digits >= 17) { 1875 | return RYU_INPUT_TOO_LONG; 1876 | } 1877 | m10 = 10 * m10 + (c - '0'); 1878 | if (m10 != 0) { 1879 | m10digits++; 1880 | } 1881 | } 1882 | if (i < len && ((buffer[i] == 'e') || (buffer[i] == 'E'))) { 1883 | eIndex = i; 1884 | i++; 1885 | if (i < len && ((buffer[i] == '-') || (buffer[i] == '+'))) { 1886 | signedE = buffer[i] == '-'; 1887 | i++; 1888 | } 1889 | for (; i < len; i++) { 1890 | char c = buffer[i]; 1891 | if ((c < '0') || (c > '9')) { 1892 | return RYU_MALFORMED_INPUT; 1893 | } 1894 | if (e10digits > 3) { 1895 | // TODO: Be more lenient. Return +/-Infinity or +/-0 instead. 1896 | return RYU_INPUT_TOO_LONG; 1897 | } 1898 | e10 = 10 * e10 + (c - '0'); 1899 | if (e10 != 0) { 1900 | e10digits++; 1901 | } 1902 | } 1903 | } 1904 | if (i < len) { 1905 | return RYU_MALFORMED_INPUT; 1906 | } 1907 | if (signedE) { 1908 | e10 = -e10; 1909 | } 1910 | e10 -= dotIndex < eIndex ? eIndex - dotIndex - 1 : 0; 1911 | if (m10 == 0) { 1912 | *result = signedM ? -0.0 : 0.0; 1913 | return RYU_SUCCESS; 1914 | } 1915 | 1916 | if ((m10digits + e10 <= -324) || (m10 == 0)) { 1917 | // Number is less than 1e-324, which should be rounded down to 0; 1918 | // return +/-0.0. 1919 | uint64_t ieee = ((uint64_t) signedM) << (DOUBLE_EXPONENT_BITS + 1920 | DOUBLE_MANTISSA_BITS); 1921 | *result = int64Bits2Double(ieee); 1922 | return RYU_SUCCESS; 1923 | } 1924 | if (m10digits + e10 >= 310) { 1925 | // Number is larger than 1e+309, which should be rounded to +/-Infinity. 1926 | uint64_t ieee = (((uint64_t) signedM) << (DOUBLE_EXPONENT_BITS + 1927 | DOUBLE_MANTISSA_BITS)) | (0x7ffull << DOUBLE_MANTISSA_BITS); 1928 | *result = int64Bits2Double(ieee); 1929 | return RYU_SUCCESS; 1930 | } 1931 | 1932 | // Convert to binary float m2 * 2^e2, while retaining information about 1933 | // whether the conversion was exact (trailingZeros). 1934 | int32_t e2; 1935 | uint64_t m2; 1936 | bool trailingZeros; 1937 | if (e10 >= 0) { 1938 | // The length of m * 10^e in bits is: 1939 | // log2(m10 * 10^e10) = log2(m10) + e10 log2(10) = log2(m10) + e10 + 1940 | // e10 * log2(5) 1941 | // 1942 | // We want to compute the DOUBLE_MANTISSA_BITS + 1 top-most bits (+1 1943 | // for the implicit leading one in IEEE format). We therefore choose a 1944 | // binary output exponent of 1945 | // log2(m10 * 10^e10) - (DOUBLE_MANTISSA_BITS + 1). 1946 | // 1947 | // We use floor(log2(5^e10)) so that we get at least this many bits; 1948 | // better to have an additional bit than to not have enough bits. 1949 | e2 = floor_log2(m10) + e10 + log2pow5(e10) - (DOUBLE_MANTISSA_BITS + 1); 1950 | 1951 | // We now compute [m10 * 10^e10 / 2^e2] = [m10 * 5^e10 / 2^(e2-e10)]. 1952 | // To that end, we use the DOUBLE_POW5_SPLIT table. 1953 | int j = e2 - e10 - ceil_log2pow5(e10) + DOUBLE_POW5_BITCOUNT; 1954 | assert(j >= 0); 1955 | assert(e10 < DOUBLE_POW5_TABLE_SIZE); 1956 | m2 = mulShift64(m10, DOUBLE_POW5_SPLIT[e10], j); 1957 | // We also compute if the result is exact, i.e., 1958 | // [m10 * 10^e10 / 2^e2] == m10 * 10^e10 / 2^e2. 1959 | // This can only be the case if 2^e2 divides m10 * 10^e10, which in 1960 | // turn requires that the largest power of 2 that divides m10 + e10 is 1961 | // greater than e2. If e2 is less than e10, then the result must be 1962 | // exact. Otherwise we use the existing multipleOfPowerOf2 function. 1963 | trailingZeros = e2 < e10 || (e2 - e10 < 64 && multipleOfPowerOf2(m10, 1964 | e2 - e10)); 1965 | } else { 1966 | e2 = floor_log2(m10) + e10 - ceil_log2pow5(-e10) - 1967 | (DOUBLE_MANTISSA_BITS + 1); 1968 | int j = e2 - e10 + ceil_log2pow5(-e10) - 1 + DOUBLE_POW5_INV_BITCOUNT; 1969 | assert(-e10 < DOUBLE_POW5_INV_TABLE_SIZE); 1970 | m2 = mulShift64(m10, DOUBLE_POW5_INV_SPLIT[-e10], j); 1971 | trailingZeros = multipleOfPowerOf5(m10, -e10); 1972 | } 1973 | 1974 | // Compute the final IEEE exponent. 1975 | uint32_t ieee_e2 = (uint32_t) max32(0, e2 + DOUBLE_EXPONENT_BIAS + 1976 | floor_log2(m2)); 1977 | 1978 | if (ieee_e2 > 0x7fe) { 1979 | // Final IEEE exponent is larger than the maximum representable; 1980 | // return +/-Infinity. 1981 | uint64_t ieee = (((uint64_t) signedM) << (DOUBLE_EXPONENT_BITS + 1982 | DOUBLE_MANTISSA_BITS)) | (0x7ffull << DOUBLE_MANTISSA_BITS); 1983 | *result = int64Bits2Double(ieee); 1984 | return RYU_SUCCESS; 1985 | } 1986 | 1987 | // We need to figure out how much we need to shift m2. The tricky part is 1988 | // that we need to take the final IEEE exponent into account, so we need to 1989 | // reverse the bias and also special-case the value 0. 1990 | int32_t shift = (ieee_e2 == 0 ? 1 : ieee_e2) - e2 - DOUBLE_EXPONENT_BIAS - 1991 | DOUBLE_MANTISSA_BITS; 1992 | assert(shift >= 0); 1993 | 1994 | // We need to round up if the exact value is more than 0.5 above the value 1995 | // we computed. That's equivalent to checking if the last removed bit was 1 1996 | // and either the value was not just trailing zeros or the result would 1997 | // otherwise be odd. 1998 | // 1999 | // We need to update trailingZeros given that we have the exact output 2000 | // exponent ieee_e2 now. 2001 | trailingZeros &= (m2 & ((1ull << (shift - 1)) - 1)) == 0; 2002 | uint64_t lastRemovedBit = (m2 >> (shift - 1)) & 1; 2003 | bool roundUp = (lastRemovedBit != 0) && (!trailingZeros || (((m2 >> shift) 2004 | & 1) != 0)); 2005 | 2006 | uint64_t ieee_m2 = (m2 >> shift) + roundUp; 2007 | assert(ieee_m2 <= (1ull << (DOUBLE_MANTISSA_BITS + 1))); 2008 | ieee_m2 &= (1ull << DOUBLE_MANTISSA_BITS) - 1; 2009 | if (ieee_m2 == 0 && roundUp) { 2010 | // Due to how the IEEE represents +/-Infinity, we don't need to check 2011 | // for overflow here. 2012 | ieee_e2++; 2013 | } 2014 | 2015 | uint64_t ieee = (((((uint64_t) signedM) << DOUBLE_EXPONENT_BITS) | 2016 | (uint64_t)ieee_e2) << DOUBLE_MANTISSA_BITS) | ieee_m2; 2017 | *result = int64Bits2Double(ieee); 2018 | return RYU_SUCCESS; 2019 | } 2020 | 2021 | #define FLOAT_MANTISSA_BITS 23 2022 | #define FLOAT_EXPONENT_BITS 8 2023 | #define FLOAT_EXPONENT_BIAS 127 2024 | 2025 | static inline uint32_t floor_log2_32(const uint32_t value) { 2026 | return 31 - __builtin_clz(value); 2027 | } 2028 | 2029 | static inline float int32Bits2Float(uint32_t bits) { 2030 | float f; 2031 | memcpy(&f, &bits, sizeof(float)); 2032 | return f; 2033 | } 2034 | 2035 | static enum RyuStatus s2f_n(const char * buffer, const int len, float * result){ 2036 | if (len == 0) { 2037 | return RYU_INPUT_TOO_SHORT; 2038 | } 2039 | int m10digits = 0; 2040 | int e10digits = 0; 2041 | int dotIndex = len; 2042 | int eIndex = len; 2043 | uint32_t m10 = 0; 2044 | int32_t e10 = 0; 2045 | bool signedM = false; 2046 | bool signedE = false; 2047 | int i = 0; 2048 | if (buffer[i] == '-') { 2049 | signedM = true; 2050 | i++; 2051 | } 2052 | for (; i < len; i++) { 2053 | char c = buffer[i]; 2054 | if (c == '.') { 2055 | if (dotIndex != len) { 2056 | return RYU_MALFORMED_INPUT; 2057 | } 2058 | dotIndex = i; 2059 | continue; 2060 | } 2061 | if ((c < '0') || (c > '9')) { 2062 | break; 2063 | } 2064 | if (m10digits >= 9) { 2065 | return RYU_INPUT_TOO_LONG; 2066 | } 2067 | m10 = 10 * m10 + (c - '0'); 2068 | if (m10 != 0) { 2069 | m10digits++; 2070 | } 2071 | } 2072 | if (i < len && ((buffer[i] == 'e') || (buffer[i] == 'E'))) { 2073 | eIndex = i; 2074 | i++; 2075 | if (i < len && ((buffer[i] == '-') || (buffer[i] == '+'))) { 2076 | signedE = buffer[i] == '-'; 2077 | i++; 2078 | } 2079 | for (; i < len; i++) { 2080 | char c = buffer[i]; 2081 | if ((c < '0') || (c > '9')) { 2082 | return RYU_MALFORMED_INPUT; 2083 | } 2084 | if (e10digits > 3) { 2085 | // TODO: Be more lenient. Return +/-Infinity or +/-0 instead. 2086 | return RYU_INPUT_TOO_LONG; 2087 | } 2088 | e10 = 10 * e10 + (c - '0'); 2089 | if (e10 != 0) { 2090 | e10digits++; 2091 | } 2092 | } 2093 | } 2094 | if (i < len) { 2095 | return RYU_MALFORMED_INPUT; 2096 | } 2097 | if (signedE) { 2098 | e10 = -e10; 2099 | } 2100 | e10 -= dotIndex < eIndex ? eIndex - dotIndex - 1 : 0; 2101 | if (m10 == 0) { 2102 | *result = signedM ? -0.0f : 0.0f; 2103 | return RYU_SUCCESS; 2104 | } 2105 | 2106 | if ((m10digits + e10 <= -46) || (m10 == 0)) { 2107 | // Number is less than 1e-46, which should be rounded down to 0; 2108 | // return +/-0.0. 2109 | uint32_t ieee = ((uint32_t) signedM) << (FLOAT_EXPONENT_BITS + 2110 | FLOAT_MANTISSA_BITS); 2111 | *result = int32Bits2Float(ieee); 2112 | return RYU_SUCCESS; 2113 | } 2114 | if (m10digits + e10 >= 40) { 2115 | // Number is larger than 1e+39, which should be rounded to +/-Infinity. 2116 | uint32_t ieee = (((uint32_t) signedM) << (FLOAT_EXPONENT_BITS + 2117 | FLOAT_MANTISSA_BITS)) | (0xffu << FLOAT_MANTISSA_BITS); 2118 | *result = int32Bits2Float(ieee); 2119 | return RYU_SUCCESS; 2120 | } 2121 | 2122 | // Convert to binary float m2 * 2^e2, while retaining information about 2123 | // whether the conversion was exact (trailingZeros). 2124 | int32_t e2; 2125 | uint32_t m2; 2126 | bool trailingZeros; 2127 | if (e10 >= 0) { 2128 | // The length of m * 10^e in bits is: 2129 | // log2(m10 * 10^e10) = log2(m10) + e10 log2(10) = log2(m10) + e10 + 2130 | // e10 * log2(5) 2131 | // 2132 | // We want to compute the FLOAT_MANTISSA_BITS + 1 top-most bits (+1 for 2133 | // the implicit leading one in IEEE format). We therefore choose a 2134 | // binary output exponent of 2135 | // log2(m10 * 10^e10) - (FLOAT_MANTISSA_BITS + 1). 2136 | // 2137 | // We use floor(log2(5^e10)) so that we get at least this many bits; 2138 | // better to have an additional bit than to not have enough bits. 2139 | e2 = floor_log2_32(m10) + e10 + log2pow5(e10) - (FLOAT_MANTISSA_BITS + 2140 | 1); 2141 | 2142 | // We now compute [m10 * 10^e10 / 2^e2] = [m10 * 5^e10 / 2^(e2-e10)]. 2143 | // To that end, we use the FLOAT_POW5_SPLIT table. 2144 | int j = e2 - e10 - ceil_log2pow5(e10) + FLOAT_POW5_BITCOUNT; 2145 | assert(j >= 0); 2146 | m2 = mulPow5divPow2(m10, e10, j); 2147 | 2148 | // We also compute if the result is exact, i.e., 2149 | // [m10 * 10^e10 / 2^e2] == m10 * 10^e10 / 2^e2. 2150 | // This can only be the case if 2^e2 divides m10 * 10^e10, which in 2151 | // turn requires that the largest power of 2 that divides m10 + e10 is 2152 | // greater than e2. If e2 is less than e10, then the result must be 2153 | // exact. Otherwise we use the existing multipleOfPowerOf2 function. 2154 | trailingZeros = e2 < e10 || (e2 - e10 < 32 && multipleOfPowerOf2_32(m10, 2155 | e2 - e10)); 2156 | } else { 2157 | e2 = floor_log2_32(m10) + e10 - ceil_log2pow5(-e10) - 2158 | (FLOAT_MANTISSA_BITS + 1); 2159 | 2160 | // We now compute [m10 * 10^e10 / 2^e2] = [m10 / (5^(-e10) 2^(e2-e10))]. 2161 | int j = e2 - e10 + ceil_log2pow5(-e10) - 1 + FLOAT_POW5_INV_BITCOUNT; 2162 | m2 = mulPow5InvDivPow2(m10, -e10, j); 2163 | 2164 | // We also compute if the result is exact, i.e., 2165 | // [m10 / (5^(-e10) 2^(e2-e10))] == m10 / (5^(-e10) 2^(e2-e10)) 2166 | // 2167 | // If e2-e10 >= 0, we need to check whether (5^(-e10) 2^(e2-e10)) 2168 | // divides m10, which is the case iff pow5(m10) >= -e10 AND 2169 | // pow2(m10) >= e2-e10. 2170 | // 2171 | // If e2-e10 < 0, we have actually computed 2172 | // [m10 * 2^(e10 e2) / 5^(-e10)] above, and we need to check 2173 | // whether 5^(-e10) divides (m10 * 2^(e10-e2)), which is the case iff 2174 | // pow5(m10 * 2^(e10-e2)) = pow5(m10) >= -e10. 2175 | trailingZeros = (e2 < e10 || (e2 - e10 < 32 && 2176 | multipleOfPowerOf2_32(m10, e2 - e10))) && 2177 | multipleOfPowerOf5_32(m10, -e10); 2178 | } 2179 | 2180 | // Compute the final IEEE exponent. 2181 | uint32_t ieee_e2 = (uint32_t) max32(0, e2 + FLOAT_EXPONENT_BIAS + 2182 | floor_log2_32(m2)); 2183 | 2184 | if (ieee_e2 > 0xfe) { 2185 | // Final IEEE exponent is larger than the maximum representable; 2186 | // return +/-Infinity. 2187 | uint32_t ieee = (((uint32_t) signedM) << (FLOAT_EXPONENT_BITS + 2188 | FLOAT_MANTISSA_BITS)) | (0xffu << FLOAT_MANTISSA_BITS); 2189 | *result = int32Bits2Float(ieee); 2190 | return RYU_SUCCESS; 2191 | } 2192 | 2193 | // We need to figure out how much we need to shift m2. The tricky part is 2194 | // that we need to take the final IEEE exponent into account, so we need 2195 | // to reverse the bias and also special-case the value 0. 2196 | int32_t shift = (ieee_e2 == 0 ? 1 : ieee_e2) - e2 - FLOAT_EXPONENT_BIAS - 2197 | FLOAT_MANTISSA_BITS; 2198 | assert(shift >= 0); 2199 | 2200 | // We need to round up if the exact value is more than 0.5 above the value 2201 | // we computed. That's equivalent to checking if the last removed bit was 2202 | // 1 and either the value was not just trailing zeros or the result would 2203 | // otherwise be odd. 2204 | // 2205 | // We need to update trailingZeros given that we have the exact output 2206 | // exponent ieee_e2 now. 2207 | trailingZeros &= (m2 & ((1u << (shift - 1)) - 1)) == 0; 2208 | uint32_t lastRemovedBit = (m2 >> (shift - 1)) & 1; 2209 | bool roundUp = (lastRemovedBit != 0) && (!trailingZeros || (((m2 >> shift) 2210 | & 1) != 0)); 2211 | 2212 | uint32_t ieee_m2 = (m2 >> shift) + roundUp; 2213 | assert(ieee_m2 <= (1u << (FLOAT_MANTISSA_BITS + 1))); 2214 | ieee_m2 &= (1u << FLOAT_MANTISSA_BITS) - 1; 2215 | if (ieee_m2 == 0 && roundUp) { 2216 | // Rounding up may overflow the mantissa. 2217 | // In this case we move a trailing zero of the mantissa into the 2218 | // exponent. 2219 | // Due to how the IEEE represents +/-Infinity, we don't need to check 2220 | // for overflow here. 2221 | ieee_e2++; 2222 | } 2223 | uint32_t ieee = (((((uint32_t) signedM) << FLOAT_EXPONENT_BITS) | 2224 | (uint32_t)ieee_e2) << FLOAT_MANTISSA_BITS) | ieee_m2; 2225 | *result = int32Bits2Float(ieee); 2226 | return RYU_SUCCESS; 2227 | } 2228 | 2229 | struct fp_writer { 2230 | uint8_t *dst; 2231 | size_t n; 2232 | size_t count; 2233 | }; 2234 | 2235 | static void fp_write_nullterm(struct fp_writer *wr) { 2236 | if (wr->n > wr->count) wr->dst[wr->count] = '\0'; 2237 | else if (wr->n > 0) wr->dst[wr->n-1] = '\0'; 2238 | } 2239 | 2240 | static void fp_write_char(struct fp_writer *wr, char b) { 2241 | if (wr->count < wr->n) wr->dst[wr->count] = b; 2242 | wr->count++; 2243 | } 2244 | 2245 | struct fp_info { 2246 | bool ok; // number is valid 2247 | bool sign; // has sign. Is a negative number 2248 | size_t frac; // has dot. Index of '.' or zero if none 2249 | size_t exp; // has exponent. Index of 'e' or zero if none 2250 | size_t len; // number of bytes parsed 2251 | }; 2252 | 2253 | /// Parses the next number from a data stream and returns information. 2254 | /// This is compatible with JSON, WKT, and general numerical values. 2255 | /// This does not convert the data into a number. 2256 | /// It only get basic information for validation and later parsing. 2257 | FP_EXTERN struct fp_info fp_parse(const char *data, size_t len) { 2258 | size_t i = 0; 2259 | bool sign = false; 2260 | size_t frac = 0; 2261 | size_t exp = 0; 2262 | if (i == len) { 2263 | goto fail; 2264 | } 2265 | // sign 2266 | if (data[i] == '-') { 2267 | sign = true; 2268 | i++; 2269 | if (i == len) { 2270 | goto fail; 2271 | } 2272 | if (data[i] < '0' || data[i] > '9') { 2273 | goto fail; 2274 | } 2275 | } 2276 | // int 2277 | if (i == len) { 2278 | goto fail; 2279 | } 2280 | if (data[i] == '0') { 2281 | i++; 2282 | } else { 2283 | for (; i < len; i++) { 2284 | if (data[i] >= '0' && data[i] <= '9') { 2285 | continue; 2286 | } 2287 | break; 2288 | } 2289 | } 2290 | if (i == len) { 2291 | goto ok; 2292 | } 2293 | // frac 2294 | if (data[i] == '.') { 2295 | frac = i; 2296 | i++; 2297 | if (i == len) { 2298 | goto fail; 2299 | } 2300 | if (data[i] < '0' || data[i] > '9') { 2301 | goto fail; 2302 | } 2303 | i++; 2304 | for (; i < len; i++) { 2305 | if (data[i] >= '0' && data[i] <= '9') { 2306 | continue; 2307 | } 2308 | break; 2309 | } 2310 | } 2311 | if (i == len) { 2312 | goto ok; 2313 | } 2314 | // exp 2315 | if (data[i] == 'e' || data[i] == 'E') { 2316 | exp = i; 2317 | i++; 2318 | if (i == len) { 2319 | goto fail; 2320 | } 2321 | if (data[i] == '+' || data[i] == '-') { 2322 | i++; 2323 | } 2324 | if (i == len) { 2325 | goto fail; 2326 | } 2327 | if (data[i] < '0' || data[i] > '9') { 2328 | goto fail; 2329 | } 2330 | i++; 2331 | for (; i < len; i++) { 2332 | if (data[i] >= '0' && data[i] <= '9') { 2333 | continue; 2334 | } 2335 | break; 2336 | } 2337 | } 2338 | ok: 2339 | return (struct fp_info){ true, sign, frac, exp, i }; 2340 | fail: 2341 | return (struct fp_info){ false, sign, frac, exp, i }; 2342 | } 2343 | 2344 | union fpoint { 2345 | double d; 2346 | float f; 2347 | }; 2348 | 2349 | static size_t fp_utoa(union fpoint fpoint, int bits, char fmt, 2350 | char dst[], size_t nbytes) 2351 | { 2352 | struct fp_writer wr = { .dst = (uint8_t*)dst, .n = nbytes }; 2353 | char buf[25]; 2354 | bool f = true; 2355 | bool g = false; 2356 | bool j = false; 2357 | char ech = 'e'; 2358 | switch (fmt) { 2359 | case 'j': case 'J': 2360 | fmt -= 3; 2361 | j = true; 2362 | // fall through 2363 | case 'g': case 'G': 2364 | fmt -= 2; 2365 | g = true; 2366 | // fall through 2367 | case 'e': case 'E': 2368 | f = g; 2369 | if (fmt == 'E') ech = 'E'; 2370 | // fall through 2371 | case 'f': 2372 | if (bits == 32) { 2373 | f2s_buffered(fpoint.f, buf); 2374 | } else { 2375 | d2s_buffered(fpoint.d, buf); 2376 | } 2377 | break; 2378 | default: 2379 | buf[0] = '\0'; 2380 | } 2381 | bool neg = false; 2382 | char *p = buf; 2383 | if (p[0] == '-') { 2384 | fp_write_char(&wr, '-'); 2385 | p++; 2386 | neg = true; 2387 | } 2388 | char *end = p; 2389 | char *e = NULL; 2390 | while (*end) { 2391 | if (*end >= 'E' && (*end == 'E' || *end == 'e')) { 2392 | e = end; 2393 | } 2394 | end++; 2395 | } 2396 | if (!e) { 2397 | if (*p == 'i' || *p == 'I') { 2398 | strcpy(p, "Infinity"); 2399 | } else if (*p == 'n' || *p == 'N') { 2400 | strcpy(p, "NaN"); 2401 | } else { 2402 | *p = '\0'; 2403 | } 2404 | while (*p) fp_write_char(&wr, *(p++)); 2405 | fp_write_nullterm(&wr); 2406 | return wr.count; 2407 | } 2408 | if (!f) { 2409 | *e = '\0'; 2410 | while (*p) fp_write_char(&wr, *(p++)); 2411 | fp_write_char(&wr, ech); 2412 | p++; 2413 | if (j && *p != '-') fp_write_char(&wr, '+'); 2414 | while (*p) fp_write_char(&wr, *(p++)); 2415 | fp_write_nullterm(&wr); 2416 | return wr.count; 2417 | } 2418 | int en = atoi(e+1); 2419 | *e = '\0'; 2420 | if (en < 0) { 2421 | fp_write_char(&wr, '0'); 2422 | fp_write_char(&wr, '.'); 2423 | en = -en; 2424 | for (int i = 0; i < en-1; i++) { 2425 | fp_write_char(&wr, '0'); 2426 | } 2427 | fp_write_char(&wr, *(p++)); 2428 | if (*p) { 2429 | p++; 2430 | while (*p) fp_write_char(&wr, *(p++)); 2431 | } 2432 | } else { 2433 | fp_write_char(&wr, *(p++)); 2434 | if (*p) p++; 2435 | for (int i = 0; i < en; i++) { 2436 | if (*p) { 2437 | fp_write_char(&wr, *(p++)); 2438 | } else { 2439 | fp_write_char(&wr, '0'); 2440 | } 2441 | } 2442 | if (*p && !(*p == '0' && *(p+1) == '\0')) { 2443 | fp_write_char(&wr, '.'); 2444 | while (*p) fp_write_char(&wr, *(p++)); 2445 | } 2446 | } 2447 | fp_write_nullterm(&wr); 2448 | if (g) { 2449 | bool rewrite = false; 2450 | if (j) { 2451 | rewrite = neg ? wr.count > 22 : wr.count > 21; 2452 | } else { 2453 | rewrite = (size_t)(end-buf) < wr.count; 2454 | } 2455 | if (rewrite) { 2456 | // rewind and rewrite the buffer 2457 | wr = (struct fp_writer){ .dst = (uint8_t*)dst, .n = nbytes }; 2458 | p = buf; 2459 | *e = '\0'; 2460 | while (*p) fp_write_char(&wr, *(p++)); 2461 | fp_write_char(&wr, ech); 2462 | p++; 2463 | if (j && *p != '-') fp_write_char(&wr, '+'); 2464 | while (*p) fp_write_char(&wr, *(p++)); 2465 | fp_write_nullterm(&wr); 2466 | } 2467 | } 2468 | return wr.count; 2469 | } 2470 | 2471 | /// fp_dtoa converts a double into a string representation that is copied 2472 | /// into the provided C string buffer. 2473 | /// 2474 | /// Returns the number of characters, not including the null-terminator, needed 2475 | /// to store the double into the C string buffer. 2476 | /// If the returned length is greater than nbytes-1, then only a parital copy 2477 | /// occurred. 2478 | /// 2479 | /// The format is one of 2480 | /// 'e' (-d.ddddedd, a decimal exponent) 2481 | /// 'E' (-d.ddddEdd, a decimal exponent) 2482 | /// 'f' (-ddd.dddd, no exponent) 2483 | /// 'g' ('e' for large exponents, 'f' otherwise) 2484 | /// 'G' ('E' for large exponents, 'f' otherwise) 2485 | /// 'j' ('e' for large exponents, 'f' otherwise) (matches javascript format) 2486 | /// 'J' ('E' for large exponents, 'f' otherwise) (matches javascript format) 2487 | FP_EXTERN size_t fp_dtoa(double d, char fmt, char dst[], size_t n) { 2488 | return fp_utoa((union fpoint){ .d = d }, 64, fmt, dst, n); 2489 | } 2490 | 2491 | /// fp_ftoa converts a float into a string representation that is copied 2492 | /// into the provided C string buffer. 2493 | /// 2494 | /// Returns the number of characters, not including the null-terminator, needed 2495 | /// to store the float into the C string buffer. 2496 | /// If the returned length is greater than nbytes-1, then only a parital copy 2497 | /// occurred. 2498 | /// 2499 | /// The format is one of 2500 | /// 'e' (-d.ddddedd, a decimal exponent) 2501 | /// 'E' (-d.ddddEdd, a decimal exponent) 2502 | /// 'f' (-ddd.dddd, no exponent) 2503 | /// 'g' ('e' for large exponents, 'f' otherwise) 2504 | /// 'G' ('E' for large exponents, 'f' otherwise) 2505 | /// 'j' ('e' for large exponents, 'f' otherwise) (matches javascript format) 2506 | /// 'J' ('E' for large exponents, 'f' otherwise) (matches javascript format) 2507 | FP_EXTERN size_t fp_ftoa(float f, char fmt, char dst[], size_t n) { 2508 | return fp_utoa((union fpoint){ .f = f }, 32, fmt, dst, n); 2509 | } 2510 | 2511 | // s2d_n is very strict and will sometime return RYU_INPUT_TOO_LONG even 2512 | // though the number is correct, albeit just a very long string. 2513 | // In that case fallback to the built-in strtod(). 2514 | #define fp_fallback_clib(func) if (len > 0) { \ 2515 | char *end; \ 2516 | errno = 0; \ 2517 | *x = func(data, &end); \ 2518 | ok = (size_t)(end-data) == len && errno == 0; \ 2519 | if (!ok) { \ 2520 | *x = NAN; \ 2521 | } \ 2522 | } 2523 | 2524 | /// Convert a string to a double 2525 | /// Returns false if the input is invalid 2526 | FP_EXTERN bool fp_atod(const char *data, size_t len, double *x) { 2527 | *x = NAN; 2528 | bool ok = s2d_n(data, len, x) == RYU_SUCCESS; 2529 | if (!ok) { 2530 | fp_fallback_clib(strtod); 2531 | } 2532 | return ok; 2533 | } 2534 | 2535 | /// Convert a string to a float 2536 | /// Returns false if the input is invalid 2537 | FP_EXTERN bool fp_atof(const char *data, size_t len, float *x) { 2538 | *x = NAN; 2539 | bool ok = s2f_n(data, len, x) == RYU_SUCCESS; 2540 | if (!ok) { 2541 | fp_fallback_clib(strtof); 2542 | } 2543 | return ok; 2544 | } 2545 | -------------------------------------------------------------------------------- /fp.h: -------------------------------------------------------------------------------- 1 | // https://github.com/tidwall/fp 2 | // 3 | // Copyright 2025 Joshua J Baker. All rights reserved. 4 | // Use of this source code is governed by an MIT-style 5 | // license that can be found in the LICENSE file. 6 | 7 | #ifndef FP_H 8 | #define FP_H 9 | 10 | #include 11 | #include 12 | 13 | size_t fp_dtoa(double d, char fmt, char dst[], size_t n); 14 | size_t fp_ftoa(float f, char fmt, char dst[], size_t n); 15 | bool fp_atod(const char *data, size_t len, double *x); 16 | bool fp_atof(const char *data, size_t len, float *x); 17 | 18 | struct fp_info { 19 | bool ok; // number is valid 20 | bool sign; // has sign. Is a negative number 21 | size_t frac; // has dot. Index of '.' or zero if none 22 | size_t exp; // has exponent. Index of 'e' or zero if none 23 | size_t len; // number of bytes parsed 24 | }; 25 | 26 | struct fp_info fp_parse(const char *data, size_t len); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "fp.h" 8 | 9 | #define test(fmt, input, expected) { \ 10 | char buf[256]; \ 11 | size_t n = fp_dtoa((input), (fmt), buf, sizeof(buf)); \ 12 | if (strcmp(buf, (expected)) != 0) { \ 13 | fprintf(stderr, "line %d: expected %s, got %s\n", \ 14 | __LINE__, (expected), buf); \ 15 | exit(1); \ 16 | } \ 17 | assert(n == strlen(buf)); \ 18 | double x; \ 19 | assert(fp_atod(buf, n, &x)); \ 20 | char buf2[256]; \ 21 | size_t n2 = fp_dtoa(x, (fmt), buf2, sizeof(buf)); \ 22 | assert(n == n2); \ 23 | assert(strcmp(buf, buf2) == 0); \ 24 | } 25 | 26 | #define test_j(input) { \ 27 | char buf0[256]; \ 28 | strcpy(buf0, #input); \ 29 | if (buf0[strlen(buf0)-2] == '.') { \ 30 | buf0[strlen(buf0)-2] = '\0'; \ 31 | test('j', input, buf0); \ 32 | test('J', input, buf0); \ 33 | } else { \ 34 | char *e = strchr(buf0, 'e'); \ 35 | if (!e) e = strchr(buf0, 'E'); \ 36 | assert(e); \ 37 | *e = 'e'; \ 38 | test('j', input, buf0); \ 39 | *e = 'E'; \ 40 | test('J', input, buf0); \ 41 | } \ 42 | } 43 | 44 | int main(void) { 45 | test('f', 212123123.123188832, "212123123.12318882"); 46 | test('e', 212123123.123188832, "2.1212312312318882e8"); 47 | test('E', 212123123.123188832, "2.1212312312318882E8"); 48 | test('f', 9223372036854775808.0, "9223372036854776000"); 49 | test('f', 0.000123123001, "0.000123123001"); 50 | test('f', 1.3441331, "1.3441331"); 51 | test('f', 1.0, "1"); 52 | test('f', -1.0, "-1"); 53 | test('f', -0.0, "-0"); 54 | test('f', 0.5, "0.5"); 55 | test('f', -0.5, "-0.5"); 56 | test('f', 0.0, "0"); 57 | test('f', -0.0, "-0"); 58 | test('f', 0.5, "0.5"); 59 | test('f', -0.5, "-0.5"); 60 | test('f', 0.0, "0"); 61 | test('f', -0.01, "-0.01"); 62 | test('f', -0.015, "-0.015"); 63 | test('f', 5000.0, "5000"); 64 | test('f', 0000.0, "0"); 65 | test('f', -0000.0, "-0"); 66 | test('f', 5123.0, "5123"); 67 | test('f', 5000000000000000000.0, "5000000000000000000"); 68 | test('f', -0.00000000000000005, "-0.00000000000000005"); 69 | char buf[32]; 70 | size_t n1 = fp_dtoa(-112.89123883, 'f', buf, sizeof(buf)); 71 | assert(strcmp(buf, "-112.89123883") == 0); 72 | size_t n2 = fp_dtoa(-112.89123883, 'f', NULL, 0); 73 | assert(n1 == n2); 74 | size_t n3 = fp_dtoa(-112.89123883, 'f', buf, 5); 75 | assert(n3 == n2); 76 | assert(strcmp(buf, "-112") == 0); 77 | fp_dtoa(-112.89123883, 'f', buf, 1); 78 | assert(strcmp(buf, "") == 0); 79 | fp_dtoa(-112.89123883, 'f', buf, 2); 80 | assert(strcmp(buf, "-") == 0); 81 | fp_dtoa(-112.89123883, 'f', buf, 6); 82 | assert(strcmp(buf, "-112.") == 0); 83 | test('g', -0.01, "-0.01"); 84 | test('f', 5000000000000000000.0, "5000000000000000000"); 85 | test('e', 5000000000000000000.0, "5e18"); 86 | test('g', 5000000000000000000.0, "5e18"); 87 | test('j', 5000000000000000000.0, "5000000000000000000"); 88 | test('f', 50000000000000000001.0, "50000000000000000000"); 89 | test('e', 50000000000000000001.0, "5e19"); 90 | test('g', 50000000000000000001.0, "5e19"); 91 | test('j', 50000000000000000001.0, "50000000000000000000"); 92 | test('f', 500000000000000000011.0, "500000000000000000000"); 93 | test('e', 500000000000000000011.0, "5e20"); 94 | test('g', 500000000000000000011.0, "5e20"); 95 | test('j', 500000000000000000011.0, "500000000000000000000"); 96 | test('f', -500000000000000000011.0, "-500000000000000000000"); 97 | test('e', -500000000000000000011.0, "-5e20"); 98 | test('g', -500000000000000000011.0, "-5e20"); 99 | test('j', -500000000000000000011.0, "-500000000000000000000"); 100 | test('f', 5000000000000000000111.0, "5000000000000000000000"); 101 | test('e', 5000000000000000000111.0, "5e21"); 102 | test('g', 5000000000000000000111.0, "5e21"); 103 | test('j', 5000000000000000000111.0, "5e+21"); 104 | test('f', -5000000000000000000111.0, "-5000000000000000000000"); 105 | test('e', -5000000000000000000111.0, "-5e21"); 106 | test('g', -5000000000000000000111.0, "-5e21"); 107 | test('j', -5000000000000000000111.0, "-5e+21"); 108 | test('f', 5000, "5000"); 109 | test('g', 5000, "5e3"); 110 | test('f', 500, "500"); 111 | test('g', 500, "500"); 112 | test('g', 500.1, "500.1"); 113 | test('e', 500.1123, "5.001123e2"); 114 | test('g', 500.1123, "500.1123"); 115 | test('e', 500.1123890123, "5.001123890123e2"); 116 | test('g', 500.1123890123, "500.1123890123"); 117 | test('e', 500123.1123890123, "5.001231123890123e5"); 118 | test('g', 500123.1123890123, "500123.1123890123"); 119 | test('e', -500123.1123890123, "-5.001231123890123e5"); 120 | test('g', -500123.1123890123, "-500123.1123890123"); 121 | test('e', 5001237.1123890123, "5.001237112389012e6"); 122 | test('g', 5001237.1123890123, "5001237.112389012"); 123 | test('e', 5001237910.1123890123, "5.001237910112389e9"); 124 | test('g', 5001237910.1123890123, "5001237910.112389"); 125 | test('e', 50012379109182039182.1123890123, "5.001237910918204e19"); 126 | test('g', 50012379109182039182.1123890123, "50012379109182040000"); 127 | test('e', 8888888899999999999999999.0, "8.8888889e24"); 128 | test('g', 8888888899999999999999999.0, "8.8888889e24"); 129 | 130 | test_j(35499548951617827000.0); 131 | test_j(2.1622774220303696e+23); 132 | test_j(426169229454865500000.0); 133 | test_j(1.1122428779605864e+22); 134 | test_j(208689857201900700000.0); 135 | test_j(9.215635951632788e+21); 136 | test_j(394363363386584860000.0); 137 | test_j(1.051552966719607e+21); 138 | test_j(619416341368231300000.0); 139 | test_j(1.855027370624036e+21); 140 | test_j(104781779522236330000.0); 141 | test_j(1.0142892004126468e+21); 142 | test_j(109047775277613840000.0); 143 | test_j(1.0842409975308099e+21); 144 | test_j(9195049728998015000.0); 145 | test_j(4.778131141654174e+21); 146 | test_j(62529739735412620000.0); 147 | test_j(1.1320063478633598e+21); 148 | test_j(196145233329870600000.0); 149 | test_j(1.8174708505162005e+21); 150 | test_j(373792539196554600000.0); 151 | test_j(3.0212836059446253e+21); 152 | test_j(72267036244919420000.0); 153 | test_j(2.664955831891294e+22); 154 | test_j(52935469346551820000.0); 155 | test_j(1.2946386961259915e+21); 156 | test_j(170603629769678500000.0); 157 | test_j(6.60526142584568e+21); 158 | test_j(42880714092059600000.0); 159 | test_j(2.362835377916814e+21); 160 | test_j(231014740272716150000.0); 161 | test_j(1.3022371556436764e+21); 162 | test_j(244316357434306170000.0); 163 | test_j(2.116436806095811e+21); 164 | test_j(5602693290733586000.0); 165 | test_j(1.2231536651405277e+22); 166 | test_j(15363133420173502000.0); 167 | test_j(7.964194881065025e+23); 168 | test_j(3681986271578664000.0); 169 | test_j(5.875116361313629e+22); 170 | test_j(115497775565041290000.0); 171 | test_j(1.5494985062998304e+21); 172 | test_j(3.332693432432603e+22); 173 | test_j(426464718456790000000.0); 174 | test_j(1.7226097008801732e+22); 175 | test_j(69957914410743990000.0); 176 | test_j(3.42160911381865e+22); 177 | test_j(1688019858430556000.0); 178 | test_j(1.9347549418669543e+22); 179 | test_j(733425086581656500000.0); 180 | test_j(2.0748775604932917e+22); 181 | test_j(147009784738754330000.0); 182 | test_j(2.086247207898731e+23); 183 | test_j(987306907069234300000.0); 184 | test_j(1.489134275661723e+21); 185 | test_j(629085397883884400000.0); 186 | test_j(1.5752300766133504e+22); 187 | test_j(987306907069234300000.0); 188 | test_j(1.095564255637569e+21); 189 | test_j(836056326897382300000.0); 190 | test_j(5.556055204583265e+21); 191 | test_j(13152608998628676000.0); 192 | test_j(2.6772291512932968e+23); 193 | test_j(987306907069234300000.0); 194 | test_j(2.2811913809996984e+21); 195 | test_j(29738866232455856000.0); 196 | test_j(3.8228990573369313e+21); 197 | test_j(76926234432060640000.0); 198 | test_j(3.746067584976078e+22); 199 | test_j(987306907069234300000.0); 200 | test_j(2.958850611740982e+22); 201 | test_j(717386127925367700000.0); 202 | test_j(2.520095981091263e+23); 203 | test_j(987306907069234300000.0); 204 | test_j(1.2382226889099641e+22); 205 | test_j(68438623369146106000.0); 206 | test_j(1.3567015796774057e+23); 207 | test_j(56555442318894600000.0); 208 | test_j(1.11167738462246e+22); 209 | test_j(28021174372971598000.0); 210 | test_j(2.467622844932717e+22); 211 | test_j(540993400866745800000.0); 212 | test_j(1.2490950941404075e+22); 213 | test_j(77500474384390620000.0); 214 | test_j(2.8991807958122163e+22); 215 | test_j(253113508231971300000.0); 216 | test_j(5.307740298202583E+22); 217 | test_j(186872634142835570000.0); 218 | 219 | double x; 220 | assert(fp_atod("123.456", 7, &x) && x == 123.456); 221 | assert(!fp_atod("A23.456", 7, &x) && isnan(x)); 222 | assert(!fp_atod("", 0, &x) && isnan(x)); 223 | assert(!fp_atod(0, 0, &x) && isnan(x)); 224 | float y; 225 | assert(fp_atof("123.456", 7, &y) && y == 123.456f); 226 | assert(!fp_atof("A23.456", 7, &y) && isnan(y)); 227 | assert(!fp_atof("", 0, &y) && isnan(y)); 228 | assert(!fp_atof(0, 0, &y) && isnan(y)); 229 | 230 | 231 | char *list = 232 | "1230456078.90123e10\n" 233 | "-7750609.598126\n" 234 | "19688.27920015702\n" 235 | "731575400000\n" 236 | "97967.0432226889\n" 237 | "1216277862.336918\n"; 238 | 239 | size_t list_len = strlen(list); 240 | printf("\n"); 241 | printf("For the following floating point strings:\n"); 242 | printf("\n"); 243 | for (size_t i = 0; i < list_len; i++) { 244 | struct fp_info info = fp_parse(list+i, list_len-i); 245 | if (!info.ok) { 246 | // Number is invalid 247 | abort(); 248 | } 249 | printf("%.*s\n", (int)info.len, list+i); 250 | i += info.len; 251 | } 252 | printf("\n"); 253 | printf("\n"); 254 | 255 | printf("Using 'g' format:\n"); 256 | printf("\n"); 257 | printf("+---------------------+--------------+\n"); 258 | printf("| fp | printf |\n"); 259 | printf("+---------------------+--------------+\n"); 260 | for (size_t i = 0; i < list_len; i++) { 261 | struct fp_info info = fp_parse(list+i, list_len-i); 262 | if (!info.ok) { 263 | // Number is invalid 264 | abort(); 265 | } 266 | double x; 267 | fp_atod(list+i, info.len, &x); 268 | char dst[32]; 269 | fp_dtoa(x, 'g', dst, sizeof(dst)); 270 | printf("| %-19s | %-12g |\n", dst, x); 271 | i += info.len; 272 | } 273 | printf("+---------------------+--------------+\n"); 274 | printf("\n"); 275 | printf("\n"); 276 | printf("Using 'e' format:\n"); 277 | printf("\n"); 278 | printf("+---------------------+---------------+\n"); 279 | printf("| fp | printf |\n"); 280 | printf("+---------------------+---------------+\n"); 281 | for (size_t i = 0; i < list_len; i++) { 282 | struct fp_info info = fp_parse(list+i, list_len-i); 283 | if (!info.ok) { 284 | // Number is invalid 285 | abort(); 286 | } 287 | double x; 288 | fp_atod(list+i, info.len, &x); 289 | char dst[32]; 290 | fp_dtoa(x, 'e', dst, sizeof(dst)); 291 | printf("| %-19s | %-13e |\n", dst, x); 292 | i += info.len; 293 | } 294 | printf("+---------------------+---------------+\n"); 295 | printf("\n"); 296 | printf("\n"); 297 | printf("Using 'f' format:\n"); 298 | printf("\n"); 299 | printf("+----------------------+-----------------------------+\n"); 300 | printf("| fp | printf |\n"); 301 | printf("+----------------------+-----------------------------+\n"); 302 | for (size_t i = 0; i < list_len; i++) { 303 | struct fp_info info = fp_parse(list+i, list_len-i); 304 | if (!info.ok) { 305 | // Number is invalid 306 | abort(); 307 | } 308 | double x; 309 | fp_atod(list+i, info.len, &x); 310 | char dst[32]; 311 | fp_dtoa(x, 'f', dst, sizeof(dst)); 312 | printf("| %-20s | %-27f |\n", dst, x); 313 | i += info.len; 314 | } 315 | printf("+----------------------+-----------------------------+\n"); 316 | 317 | printf("PASSED\n"); 318 | return 0; 319 | } 320 | --------------------------------------------------------------------------------