vivkin / gason

Lightweight and fast JSON parser for C++
MIT License
338 stars 51 forks source link

Precision error when parsing a double #29

Closed florentbr closed 7 years ago

florentbr commented 7 years ago

The function string2double introduce a precision error when an exponent expression is parsed. The floating result should be computed only once at the end from an integer rather than adjusting the floating result in each iteration.

It should be something like that:

long long number = 0;
bool is_negative = false;
int scale = 0;

// parse sign
if (*s == '-' || *s == '+'){
  is_negative = *s == '-';
  ++s;
}

// parse integer part
while (isdigit(*s))
    number = (number * 10) + (*s++ - '0');

// parse fraction part
if (*s == '.') {
    ++s;
    while (isdigit(*s)) {
        --scale;
        number = (number * 10) + (*s++ - '0');
    }
}

// set sign
if (is_negative)
  number = -number;

// parse exponent part
if (*s == 'e' || *s == 'E') {
  ++s;

  bool is_exponent_negative = false;
  if (*s == '+' || *s == '-'){
    is_exponent_negative = *s == '-';
    ++s;
  }

  int exponent = 0;
  while (isdigit(*s))
    exponent = (exponent * 10) + (*s++ - '0');

  if (is_exponent_negative)    
    exponent = -exponent;

  scale += exponent;
}

// adjust scale
double result = (double)number;
if (scale != 0)
  result *= pow(10, scale);
vivkin commented 7 years ago

Most of the precision errors solved in new version https://github.com/vivkin/jzon/blob/master/include/gason2.h#L270