LCOV - code coverage report
Current view: top level - include/flatcc/portable - grisu3_parse.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 38 165 23.0 %
Date: 2016-11-30 13:12:14 Functions: 2 3 66.7 %
Branches: 35 187 18.7 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2016 Mikkel F. Jørgensen, dvide.com
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       5                 :            :  * you may not use this file except in compliance with the License.
       6                 :            :  * You may obtain a copy of the License at
       7                 :            :  *
       8                 :            :  *     http://www.apache.org/licenses/LICENSE-2.0
       9                 :            :  *
      10                 :            :  * Unless required by applicable law or agreed to in writing, software
      11                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      12                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13                 :            :  * See the License for the specific language governing permissions and
      14                 :            :  * limitations under the License. http://www.apache.org/licenses/LICENSE-2.0
      15                 :            :  */
      16                 :            : 
      17                 :            : /*
      18                 :            :  * Port of parts of Google Double Conversion strtod functionality
      19                 :            :  * but with fallback to strtod instead of a bignum implementation.
      20                 :            :  *
      21                 :            :  * Based on grisu3 math from MathGeoLib.
      22                 :            :  *
      23                 :            :  * See also grisu3_math.h comments.
      24                 :            :  */
      25                 :            : 
      26                 :            : #ifndef GRISU3_PARSE_H
      27                 :            : #define GRISU3_PARSE_H
      28                 :            : 
      29                 :            : #ifndef UINT8_MAX
      30                 :            : #include <stdint.h>
      31                 :            : #endif
      32                 :            : 
      33                 :            : #include <stdlib.h>
      34                 :            : #include <assert.h>
      35                 :            : #include <limits.h>
      36                 :            : 
      37                 :            : #include "grisu3_math.h"
      38                 :            : 
      39                 :            : /*
      40                 :            :  * The maximum number characters a valid number may contain.  The parse
      41                 :            :  * fails if the input length is longer but the character after max len
      42                 :            :  * was part of the number.
      43                 :            :  *
      44                 :            :  * The length should not be set too high because it protects against
      45                 :            :  * overflow in the exponent part derived from the input length.
      46                 :            :  */
      47                 :            : #define GRISU3_NUM_MAX_LEN 1000
      48                 :            : 
      49                 :            : /*
      50                 :            :  * The lightweight "portable" C library recognizes grisu3 support if
      51                 :            :  * included first.
      52                 :            :  */
      53                 :            : #define grisu3_parse_double_is_defined 1
      54                 :            : 
      55                 :            : /*
      56                 :            :  * Disable to compare performance and to test diy_fp algorithm in
      57                 :            :  * broader range.
      58                 :            :  */
      59                 :            : #define GRISU3_PARSE_FAST_CASE
      60                 :            : 
      61                 :            : /* May result in a one off error, otherwise when uncertain, fall back to strtod. */
      62                 :            : //#define GRISU3_PARSE_ALLOW_ERROR
      63                 :            : 
      64                 :            : 
      65                 :            : /*
      66                 :            :  * The dec output exponent jumps in 8, so the result is offset at most
      67                 :            :  * by 7 when the input is within range.
      68                 :            :  */
      69                 :            : static int grisu3_diy_fp_cached_dec_pow(int d_exp, grisu3_diy_fp_t *p)
      70                 :            : {
      71                 :            :     const int cached_offset = -GRISU3_MIN_CACHED_EXP;
      72                 :            :     const int d_exp_dist = GRISU3_CACHED_EXP_STEP;
      73                 :            :     int i, a_exp;
      74                 :            : 
      75                 :            :     assert(GRISU3_MIN_CACHED_EXP <= d_exp);
      76                 :            :     assert(d_exp <  GRISU3_MAX_CACHED_EXP + d_exp_dist);
      77                 :            : 
      78                 :          0 :     i = (d_exp + cached_offset) / d_exp_dist;
      79                 :          0 :     a_exp = grisu3_diy_fp_pow_cache[i].d_exp;
      80                 :          0 :     p->f = grisu3_diy_fp_pow_cache[i].fract;
      81                 :          0 :     p->e = grisu3_diy_fp_pow_cache[i].b_exp;
      82                 :            : 
      83                 :            :     assert(a_exp <= d_exp);
      84                 :            :     assert(d_exp < a_exp + d_exp_dist);
      85                 :            : 
      86                 :            :     return a_exp;
      87                 :            : }
      88                 :            : 
      89                 :            : /*
      90                 :            :  * Ported from google double conversion strtod using
      91                 :            :  * MathGeoLibs diy_fp functions for grisu3 in C.
      92                 :            :  *
      93                 :            :  * ulp_half_error is set if needed to trunacted non-zero trialing
      94                 :            :  * characters.
      95                 :            :  *
      96                 :            :  * The actual value we need to encode is:
      97                 :            :  *
      98                 :            :  * (sign ? -1 : 1) * fraction * 2 ^ (exponent - fraction_exp)
      99                 :            :  * where exponent is the base 10 exponent assuming the decimal point is
     100                 :            :  * after the first digit. fraction_exp is the base 10 magnitude of the
     101                 :            :  * fraction or number of significant digits - 1.
     102                 :            :  *
     103                 :            :  * If the exponent is between 0 and 22 and the fraction is encoded in
     104                 :            :  * the lower 53 bits (the largest bit is implicit in a double, but not
     105                 :            :  * in this fraction), then the value can be trivially converted to
     106                 :            :  * double without loss of precision. If the fraction was in fact
     107                 :            :  * multiplied by trailing zeroes that we didn't convert to exponent,
     108                 :            :  * we there are larger values the 53 bits that can also be encoded
     109                 :            :  * trivially - but then it is better to handle this during parsing
     110                 :            :  * if it is worthwhile. We do not optimize for this here, because it
     111                 :            :  * can be done in a simple check before calling, and because it might
     112                 :            :  * not be worthwile to do at all since it cery likely will fail for
     113                 :            :  * numbers printed to be convertible back to double without loss.
     114                 :            :  *
     115                 :            :  * Returns 0 if conversion was not exact. In that case the vale is
     116                 :            :  * either one smaller than the correct one, or the correct one.
     117                 :            :  *
     118                 :            :  * Exponents must be range protected before calling otherwise cached
     119                 :            :  * powers will blow up.
     120                 :            :  *
     121                 :            :  * Google Double Conversion seems to prefer the following notion:
     122                 :            :  *
     123                 :            :  * x >= 10^309 => +Inf
     124                 :            :  * x <= 10^-324 => 0,
     125                 :            :  *
     126                 :            :  * max double: HUGE_VAL = 1.7976931348623157 * 10^308
     127                 :            :  * min double: 4.9406564584124654 * 10^-324
     128                 :            :  *
     129                 :            :  * Values just below or above min/max representable number
     130                 :            :  * may round towards large/small non-Inf/non-neg values.
     131                 :            :  *
     132                 :            :  * but `strtod` seems to return +/-HUGE_VAL on overflow?
     133                 :            :  */
     134                 :          0 : int grisu3_diy_fp_encode_double(uint64_t fraction, int exponent, int fraction_exp, int ulp_half_error, double *result)
     135                 :            : {
     136                 :            :     /*
     137                 :            :      * Error is measures in fractions of integers, so we scale up to get
     138                 :            :      * some resolution to represent error expressions.
     139                 :            :      */
     140                 :            :     const int log2_error_one = 3;
     141                 :            :     const int error_one = 1 << log2_error_one;
     142                 :            :     const int denorm_exp = GRISU3_D64_DENORM_EXP;
     143                 :            :     const uint64_t hidden_bit = GRISU3_D64_IMPLICIT_ONE;
     144                 :            :     const int diy_size = GRISU3_DIY_FP_FRACT_SIZE;
     145                 :            :     const int max_digits = 19;
     146                 :            : 
     147         [ #  # ]:          0 :     int error = ulp_half_error ? error_one / 2 : 0;
     148                 :          0 :     int d_exp = (exponent - fraction_exp);
     149                 :            :     int a_exp;
     150                 :            :     int o_exp;
     151                 :            :     grisu3_diy_fp_t v = { fraction, 0 };
     152                 :            :     grisu3_diy_fp_t cp;
     153                 :            :     grisu3_diy_fp_t rounded;
     154                 :            :     int mag;
     155                 :            :     int prec;
     156                 :            :     int prec_bits;
     157                 :            :     int half_way;
     158                 :            : 
     159                 :            :     /* When fractions in a double aren't stored with implicit msb fraction bit. */
     160                 :            : 
     161                 :            :     /* Shift fraction to msb. */
     162                 :            :     v = grisu3_diy_fp_normalize(v);
     163                 :            :     /* The half point error moves up while the exponent moves down. */
     164                 :          0 :     error <<= -v.e;
     165                 :            : 
     166                 :            :     a_exp = grisu3_diy_fp_cached_dec_pow(d_exp, &cp);
     167                 :            : 
     168                 :            :     /* Interpolate between cached powers at distance 8. */
     169         [ #  # ]:          0 :     if (a_exp != d_exp) {
     170                 :          0 :         int adj_exp = d_exp - a_exp - 1;
     171                 :            :         static grisu3_diy_fp_t cp_10_lut[] = {
     172                 :            :             { 0xa000000000000000ULL, -60 },
     173                 :            :             { 0xc800000000000000ULL, -57 },
     174                 :            :             { 0xfa00000000000000ULL, -54 },
     175                 :            :             { 0x9c40000000000000ULL, -50 },
     176                 :            :             { 0xc350000000000000ULL, -47 },
     177                 :            :             { 0xf424000000000000ULL, -44 },
     178                 :            :             { 0x9896800000000000ULL, -40 },
     179                 :            :         };
     180                 :            :         assert(adj_exp >= 0 && adj_exp < 7);
     181                 :          0 :         v = grisu3_diy_fp_multiply(v, cp_10_lut[adj_exp]);
     182                 :            : 
     183                 :            :         /* 20 decimal digits won't always fit in 64 bit.
     184                 :            :          * (`fraction_exp` is one less than significant decimal
     185                 :            :          * digits in fraction, e.g. 1 * 10e0).
     186                 :            :          * If we cannot fit, introduce 1/2 ulp error
     187                 :            :          * (says double conversion reference impl.) */
     188         [ #  # ]:          0 :         if (1 + fraction_exp + adj_exp > max_digits) {
     189                 :          0 :             error += error_one / 2;
     190                 :            :         }
     191                 :            :     }
     192                 :            : 
     193                 :          0 :     v = grisu3_diy_fp_multiply(v, cp);
     194                 :            :     /*
     195                 :            :      * Google double conversion claims that:
     196                 :            :      *
     197                 :            :      *   The error introduced by a multiplication of a*b equals
     198                 :            :      *     error_a + error_b + error_a*error_b/2^64 + 0.5
     199                 :            :      *   Substituting a with 'input' and b with 'cached_power' we have
     200                 :            :      *     error_b = 0.5  (all cached powers have an error of less than 0.5 ulp),
     201                 :            :      *     error_ab = 0 or 1 / error_oner > error_a*error_b/ 2^64
     202                 :            :      *
     203                 :            :      * which in our encoding becomes:
     204                 :            :      * error_a = error_one/2
     205                 :            :      * error_ab = 1 / error_one (rounds up to 1 if error != 0, or 0 * otherwise)
     206                 :            :      * fixed_error = error_one/2
     207                 :            :      *
     208                 :            :      * error += error_a + fixed_error + (error ? 1 : 0)
     209                 :            :      *
     210                 :            :      * (this isn't entirely clear, but that is as close as we get).
     211                 :            :      */
     212         [ #  # ]:          0 :     error += error_one + (error ? 1 : 0);
     213                 :            : 
     214                 :            :     o_exp = v.e;
     215                 :            :     v = grisu3_diy_fp_normalize(v);
     216                 :            :     /* Again, if we shift the significant bits, the error moves along. */
     217                 :          0 :     error <<= o_exp - v.e;
     218                 :            : 
     219                 :            :     /*
     220                 :            :      * The value `v` is bounded by 2^mag which is 64 + v.e. because we
     221                 :            :      * just normalized it by shifting towards msb.
     222                 :            :      */
     223                 :          0 :     mag = diy_size + v.e;
     224                 :            : 
     225                 :            :     /* The effective magnitude of the IEEE double representation. */
     226 [ #  # ][ #  # ]:          0 :     mag = mag >= diy_size + denorm_exp ? diy_size : mag <= denorm_exp ? 0 : mag - denorm_exp;
     227                 :          0 :     prec = diy_size - mag;
     228         [ #  # ]:          0 :     if (prec + log2_error_one >= diy_size) {
     229                 :          0 :         int e_scale = prec + log2_error_one - diy_size - 1;
     230                 :          0 :         v.f >>= e_scale;
     231                 :          0 :         v.e += e_scale;
     232                 :          0 :         error = (error >> e_scale) + 1 + error_one;
     233                 :            :         prec -= e_scale;
     234                 :            :     }
     235                 :          0 :     rounded.f = v.f >> prec;
     236                 :          0 :     rounded.e = v.e + prec;
     237                 :          0 :     prec_bits = (v.f & ((uint64_t)1 << (prec - 1))) * error_one;
     238                 :          0 :     half_way = ((uint64_t)1 << (prec - 1)) * error_one;
     239         [ #  # ]:          0 :     if (prec >= half_way + error) {
     240                 :          0 :         rounded.f++;
     241                 :            :         /* Prevent overflow. */
     242         [ #  # ]:          0 :         if (rounded.f & (hidden_bit << 1)) {
     243                 :          0 :             rounded.f >>= 1;
     244                 :          0 :             rounded.e += 1;
     245                 :            :         }
     246                 :            :     }
     247                 :          0 :     *result = grisu3_cast_double_from_diy_fp(rounded);
     248 [ #  # ][ #  # ]:          0 :     return half_way - error >= prec_bits || prec_bits >= half_way + error;
     249                 :            : }
     250                 :            : 
     251                 :            : /*
     252                 :            :  * `end` is unchanged if number is handled natively, or it is the result
     253                 :            :  * of strtod parsing in case of fallback.
     254                 :            :  */
     255                 :          5 : static const char *grisu3_encode_double(const char *buf, const char *end, int sign, uint64_t fraction, int exponent, int fraction_exp, int ulp_half_error, double *result)
     256                 :            : {
     257                 :            :     const int max_d_exp = GRISU3_D64_MAX_DEC_EXP;
     258                 :            :     const int min_d_exp = GRISU3_D64_MIN_DEC_EXP;
     259                 :            :     const double infinity = (double)GRISU3_D64_INF;
     260                 :            : 
     261                 :            :     char *v_end;
     262                 :            : 
     263                 :            :     /* Both for user experience, and to protect internal power table lookups. */
     264         [ -  + ]:          5 :     if (fraction == 0 || exponent < min_d_exp) {
     265                 :          0 :         *result = 0.0;
     266                 :          0 :         goto done;
     267                 :            :     }
     268         [ -  + ]:          5 :     if (exponent - 1 > max_d_exp) {
     269                 :          0 :         *result = infinity;
     270                 :          0 :         goto done;
     271                 :            :     }
     272                 :            : 
     273                 :            :     /*
     274                 :            :      * `exponent` is the normalized value, fraction_exp is the size of
     275                 :            :      * the representation in the `fraction value`, or one less than
     276                 :            :      * number of significant digits.
     277                 :            :      *
     278                 :            :      * If the final value can be kept in 53 bits and we can avoid
     279                 :            :      * division, then we can convert to double quite fast.
     280                 :            :      *
     281                 :            :      * ulf_half_error only happens when fraction is maxed out, so
     282                 :            :      * fraction_exp > 22 by definition.
     283                 :            :      *
     284                 :            :      * fraction_exp >= 0 always.
     285                 :            :      *
     286                 :            :      * http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
     287                 :            :      */
     288                 :            : 
     289                 :            : 
     290                 :            : #ifdef GRISU3_PARSE_FAST_CASE
     291 [ +  - ][ +  - ]:          5 :     if (fraction < (1ULL << 53) && exponent >= 0 && exponent <= 22) {
     292                 :          5 :         double v = (double)fraction;
     293                 :            :        /* Multiplying by 1e-k instead of dividing by 1ek results in rounding error. */
     294   [ -  -  -  -  :          5 :         switch (exponent - fraction_exp) {
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
                      + ]
     295                 :          0 :         case -22: v /= 1e22; break;
     296                 :          0 :         case -21: v /= 1e21; break;
     297                 :          0 :         case -20: v /= 1e20; break;
     298                 :          0 :         case -19: v /= 1e19; break;
     299                 :          0 :         case -18: v /= 1e18; break;
     300                 :          0 :         case -17: v /= 1e17; break;
     301                 :          0 :         case -16: v /= 1e16; break;
     302                 :          0 :         case -15: v /= 1e15; break;
     303                 :          0 :         case -14: v /= 1e14; break;
     304                 :          0 :         case -13: v /= 1e13; break;
     305                 :          0 :         case -12: v /= 1e12; break;
     306                 :          0 :         case -11: v /= 1e11; break;
     307                 :          0 :         case -10: v /= 1e10; break;
     308                 :          0 :         case -9: v /= 1e9; break;
     309                 :          0 :         case -8: v /= 1e8; break;
     310                 :          0 :         case -7: v /= 1e7; break;
     311                 :          0 :         case -6: v /= 1e6; break;
     312                 :          0 :         case -5: v /= 1e5; break;
     313                 :          0 :         case -4: v /= 1e4; break;
     314                 :          0 :         case -3: v /= 1e3; break;
     315                 :          0 :         case -2: v /= 1e2; break;
     316                 :          1 :         case -1: v /= 1e1; break;
     317                 :            :         case  0: break;
     318                 :          0 :         case  1: v *= 1e1; break;
     319                 :          0 :         case  2: v *= 1e2; break;
     320                 :          0 :         case  3: v *= 1e3; break;
     321                 :          0 :         case  4: v *= 1e4; break;
     322                 :          0 :         case  5: v *= 1e5; break;
     323                 :          0 :         case  6: v *= 1e6; break;
     324                 :          0 :         case  7: v *= 1e7; break;
     325                 :          0 :         case  8: v *= 1e8; break;
     326                 :          0 :         case  9: v *= 1e9; break;
     327                 :          0 :         case 10: v *= 1e10; break;
     328                 :          0 :         case 11: v *= 1e11; break;
     329                 :          0 :         case 12: v *= 1e12; break;
     330                 :          0 :         case 13: v *= 1e13; break;
     331                 :          0 :         case 14: v *= 1e14; break;
     332                 :          0 :         case 15: v *= 1e15; break;
     333                 :          0 :         case 16: v *= 1e16; break;
     334                 :          0 :         case 17: v *= 1e17; break;
     335                 :          0 :         case 18: v *= 1e18; break;
     336                 :          0 :         case 19: v *= 1e19; break;
     337                 :          0 :         case 20: v *= 1e20; break;
     338                 :          0 :         case 21: v *= 1e21; break;
     339                 :          0 :         case 22: v *= 1e22; break;
     340                 :            :         }
     341                 :          5 :         *result = v;
     342                 :          5 :         goto done;
     343                 :            :     }
     344                 :            : #endif
     345                 :            : 
     346         [ #  # ]:          0 :     if (grisu3_diy_fp_encode_double(fraction, exponent, fraction_exp, ulp_half_error, result)) {
     347                 :            :         goto done;
     348                 :            :     }
     349                 :            : #ifdef GRISU3_PARSE_ALLOW_ERROR
     350                 :            :     goto done;
     351                 :            : #endif
     352                 :          0 :     *result = strtod(buf, &v_end);
     353         [ #  # ]:          0 :     if (v_end < end) {
     354                 :          0 :         return v_end;
     355                 :            :     }
     356                 :            :     return end;
     357                 :            : done:
     358         [ -  + ]:          5 :     if (sign) {
     359                 :          0 :         *result = -*result;
     360                 :            :     }
     361                 :            :     return end;
     362                 :            : }
     363                 :            : 
     364                 :            : /*
     365                 :            :  * Returns buf if number wasn't matched, or null if number starts ok
     366                 :            :  * but contains invalid content.
     367                 :            :  */
     368                 :            : static const char *grisu3_parse_hex_fp(const char *buf, const char *end, int sign, double *result)
     369                 :            : {
     370                 :            :     (void)buf;
     371                 :            :     (void)end;
     372                 :            :     (void)sign;
     373                 :            :     *result = 0.0;
     374                 :            :     /* Not currently supported. */
     375                 :            :     return buf;
     376                 :            : }
     377                 :            : 
     378                 :            : /*
     379                 :            :  * Returns end pointer on success, or null, or buf if start is not a number.
     380                 :            :  * Sets result to 0.0 on error.
     381                 :            :  * Reads up to len + 1 bytes from buffer where len + 1 must not be a
     382                 :            :  * valid part of a number, but all of buf, buf + len need not be a
     383                 :            :  * number. Leading whitespace is NOT valid.
     384                 :            :  * Very small numbers are truncated to +/-0.0 and numerically very large
     385                 :            :  * numbers are returns as +/-infinity.
     386                 :            :  *
     387                 :            :  * A value must not end or begin with '.' (like JSON), but can have
     388                 :            :  * leading zeroes (unlike JSON). A single leading zero followed by
     389                 :            :  * an encoding symbol may or may not be interpreted as a non-decimal
     390                 :            :  * encoding prefix, e.g. 0x, but a leading zero followed by a digit is
     391                 :            :  * NOT interpreted as octal.
     392                 :            :  * A single leading negative sign may appear before digits, but positive
     393                 :            :  * sign is not allowed and space after the sign is not allowed.
     394                 :            :  * At most the first 1000 characters of the input is considered.
     395                 :            :  */
     396                 :          5 : static const char *grisu3_parse_double(const char *buf, int len, double *result)
     397                 :            : {
     398                 :            :     const char *mark, *k, *end;
     399                 :            :     int sign = 0, esign = 0;
     400                 :            :     uint64_t fraction = 0;
     401                 :            :     int exponent = 0;
     402                 :            :     int ee = 0;
     403                 :            :     int fraction_exp = 0;
     404                 :            :     int ulp_half_error = 0;
     405                 :            : 
     406                 :          5 :     *result = 0.0;
     407                 :            : 
     408                 :          5 :     end = buf + len + 1;
     409                 :            : 
     410                 :            :     /* Failsafe for exponent overflow. */
     411         [ -  + ]:          5 :     if (len > GRISU3_NUM_MAX_LEN) {
     412                 :          0 :         end = buf + GRISU3_NUM_MAX_LEN + 1;
     413                 :            :     }
     414                 :            : 
     415         [ +  - ]:          5 :     if (buf == end) {
     416                 :            :         return buf;
     417                 :            :     }
     418                 :            :     mark = buf;
     419         [ -  + ]:          5 :     if (*buf == '-') {
     420                 :          0 :         ++buf;
     421                 :            :         sign = 1;
     422         [ #  # ]:          0 :         if (buf == end) {
     423                 :            :             return 0;
     424                 :            :         }
     425                 :            :     }
     426         [ -  + ]:          5 :     if (*buf == '0') {
     427                 :          0 :         ++buf;
     428                 :            :         /* | 0x20 is lower case ASCII. */
     429 [ #  # ][ #  # ]:          0 :         if (buf != end && (*buf | 0x20) == 'x') {
     430                 :            :             k = grisu3_parse_hex_fp(buf, end, sign, result);
     431                 :            :             if (k == buf) {
     432                 :            :                 return mark;
     433                 :            :             }
     434                 :            :             return k;
     435                 :            :         }
     436                 :            :         /* Not worthwhile, except for getting the scale of integer part. */
     437 [ #  # ][ #  # ]:          0 :         while (buf != end && *buf == '0') {
     438                 :          0 :             ++buf;
     439                 :            :         }
     440                 :            :     } else {
     441         [ -  + ]:          5 :         if (*buf < '1' || *buf > '9') {
     442                 :            :             /*
     443                 :            :              * If we didn't see a sign, just don't recognize it as
     444                 :            :              * number, otherwise make it an error.
     445                 :            :              */
     446         [ #  # ]:          0 :             return sign ? 0 : mark;
     447                 :            :         }
     448                 :          5 :         fraction = *buf++ - '0';
     449                 :            :     }
     450                 :            :     k = buf;
     451                 :            :     /*
     452                 :            :      * We do not catch trailing zeroes when there is no decimal point.
     453                 :            :      * This misses an opportunity for moving the exponent down into the
     454                 :            :      * fast case. But it is unlikely to be worthwhile as it complicates
     455                 :            :      * parsing.
     456                 :            :      */
     457 [ +  - ][ -  + ]:          5 :     while (buf != end && *buf >= '0' && *buf <= '9') {
                 [ #  # ]
     458         [ #  # ]:          0 :         if (fraction >= UINT64_MAX / 10) {
     459                 :          0 :             fraction += *buf >= '5';
     460                 :            :             ulp_half_error = 1;
     461                 :          0 :             break;
     462                 :            :         }
     463                 :          0 :         fraction = fraction * 10 + *buf++ - '0';
     464                 :            :     }
     465                 :          5 :     fraction_exp = (int)(buf - k);
     466                 :            :     /* Skip surplus digits. Trailing zero does not introduce error. */
     467 [ +  - ][ -  + ]:          5 :     while (buf != end && *buf == '0') {
     468                 :          0 :         ++exponent;
     469                 :          0 :         ++buf;
     470                 :            :     }
     471 [ +  - ][ -  + ]:          5 :     if (buf != end && *buf >= '1' && *buf <= '9') {
                 [ #  # ]
     472                 :            :         ulp_half_error = 1;
     473                 :          0 :         ++exponent;
     474                 :          0 :         ++buf;
     475 [ #  # ][ #  # ]:          0 :         while (buf != end && *buf >= '0' && *buf <= '9') {
                 [ #  # ]
     476                 :          0 :             ++exponent;
     477                 :          0 :             ++buf;
     478                 :            :         }
     479                 :            :     }
     480 [ +  - ][ +  + ]:          5 :     if (buf != end && *buf == '.') {
     481                 :          1 :         ++buf;
     482                 :            :         k = buf;
     483         [ +  - ]:          1 :         if (*buf < '0' || *buf > '9') {
     484                 :            :             /* We don't accept numbers without leading or trailing digit. */
     485                 :            :             return 0;
     486                 :            :         }
     487 [ +  - ][ +  + ]:          2 :         while (buf != end && *buf >= '0' && *buf <= '9') {
                 [ +  - ]
     488         [ -  + ]:          1 :             if (fraction >= UINT64_MAX / 10) {
     489         [ #  # ]:          0 :                 if (!ulp_half_error) {
     490                 :          0 :                     fraction += *buf >= '5';
     491                 :            :                     ulp_half_error = 1;
     492                 :            :                 }
     493                 :            :                 break;
     494                 :            :             }
     495                 :          1 :             fraction = fraction * 10 + *buf++ - '0';
     496                 :          1 :             --exponent;
     497                 :            :         }
     498                 :          1 :         fraction_exp += (int)(buf - k);
     499 [ +  - ][ -  + ]:          1 :         while (buf != end && *buf == '0') {
     500                 :          0 :             ++exponent;
     501                 :          0 :             ++buf;
     502                 :            :         }
     503 [ +  - ][ -  + ]:          1 :         if (buf != end && *buf >= '1' && *buf <= '9') {
                 [ #  # ]
     504                 :            :             ulp_half_error = 1;
     505                 :          0 :             ++buf;
     506 [ #  # ][ #  # ]:          0 :             while (buf != end && *buf >= '0' && *buf <= '9') {
                 [ #  # ]
     507                 :          0 :                 ++buf;
     508                 :            :             }
     509                 :            :         }
     510                 :            :     }
     511                 :            :     /*
     512                 :            :      * Normalized exponent e.g: 1.23434e3 with fraction = 123434,
     513                 :            :      * fraction_exp = 5, exponent = 3.
     514                 :            :      * So value = fraction * 10^(exponent - fraction_exp)
     515                 :            :      */
     516                 :          5 :     exponent += fraction_exp;
     517 [ +  - ][ -  + ]:          5 :     if (buf != end && (*buf | 0x20) == 'e') {
     518         [ #  # ]:          0 :         if (end - buf < 2) {
     519                 :            :             return 0;
     520                 :            :         }
     521                 :          0 :         ++buf;
     522         [ #  # ]:          0 :         if (*buf == '+') {
     523                 :          0 :             ++buf;
     524         [ #  # ]:          0 :             if (buf == end) {
     525                 :            :                 return 0;
     526                 :            :             }
     527         [ #  # ]:          0 :         } else if (*buf == '-') {
     528                 :            :             esign = 1;
     529                 :          0 :             ++buf;
     530         [ #  # ]:          0 :             if (buf == end) {
     531                 :            :                 return 0;
     532                 :            :             }
     533                 :            :         }
     534         [ #  # ]:          0 :         if (*buf < '0' || *buf > '9') {
     535                 :            :             return 0;
     536                 :            :         }
     537                 :          0 :         ee = *buf++ - '0';
     538 [ #  # ][ #  # ]:          0 :         while (buf != end && *buf >= '0' && *buf <= '9') {
                 [ #  # ]
     539                 :            :             /*
     540                 :            :              * This test impacts performance and we do not need an
     541                 :            :              * exact value just one large enough to dominate the fraction_exp.
     542                 :            :              * Subsequent handling maps large absolute ee to 0 or infinity.
     543                 :            :              */
     544         [ #  # ]:          0 :             if (ee <= 0x7fff) {
     545                 :          0 :                 ee = ee * 10 + *buf - '0';
     546                 :            :             }
     547                 :          0 :             ++buf;
     548                 :            :         }
     549                 :            :     }
     550         [ -  + ]:          5 :     exponent = exponent + (esign ? -ee : ee);
     551                 :            : 
     552                 :            :     /*
     553                 :            :      * Exponent is now a base 10 normalized exponent so the absolute value
     554                 :            :      * is less the 10^(exponent + 1) for positive exponents. For
     555                 :            :      * denormalized doubles (using 11 bit exponent 0 with a fraction
     556                 :            :      * shiftet down, extra small numbers can be achieved.
     557                 :            :      *
     558                 :            :      * https://en.wikipedia.org/wiki/Double-precision_floating-point_format
     559                 :            :      *
     560                 :            :      * 10^-324 holds the smallest normalized exponent (but not value) and
     561                 :            :      * 10^308 holds the largest exponent. Internally our lookup table is
     562                 :            :      * only safe to use within a range slightly larger than this.
     563                 :            :      * Externally, a slightly larger/smaller value represents NaNs which
     564                 :            :      * are technically also possible to store as a number.
     565                 :            :      *
     566                 :            :      */
     567                 :            : 
     568                 :            :     /* This also protects strod fallback parsing. */
     569         [ +  - ]:          5 :     if (buf == end) {
     570                 :            :         return 0;
     571                 :            :     }
     572                 :          5 :     return grisu3_encode_double(mark, buf, sign, fraction, exponent, fraction_exp, ulp_half_error, result);
     573                 :            : }
     574                 :            : 
     575                 :            : #endif /* GRISU3_PARSE_H */

Generated by: LCOV version 1.12