double Value::readFloatText(const char * buf, size_t length) const { bool negative = false; double x = 0; bool after_point = false; double power_of_ten = 1; const char * end = buf + length; while (buf != end) { switch (*buf) { case '+': break; case '-': negative = true; break; case '.': after_point = true; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (after_point) { power_of_ten /= 10; x += (*buf - '0') * power_of_ten; } else { x *= 10; x += *buf - '0'; } break; case 'e': case 'E': { ++buf; Int32 exponent = readIntText(buf, end - buf); x *= preciseExp10(exponent); if (negative) x = -x; return x; } case 'i': case 'I': x = std::numeric_limits<double>::infinity(); if (negative) x = -x; return x; case 'n': case 'N': x = std::numeric_limits<double>::quiet_NaN(); return x; default: throwException("Cannot parse floating point number"); } ++buf; } if (negative) x = -x; return x; }
/// Прочитать число с плавающей запятой в простом формате, с грубым округлением, из не-0-terminated строки. static double readFloatText(const char * buf, const char * end) { bool negative = false; double x = 0; bool after_point = false; double power_of_ten = 1; if (buf == end) throw JSONException("JSON: cannot parse floating point number: unexpected end of data."); bool run = true; while (buf != end && run) { switch (*buf) { case '+': break; case '-': negative = true; break; case '.': after_point = true; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (after_point) { power_of_ten /= 10; x += (*buf - '0') * power_of_ten; } else { x *= 10; x += *buf - '0'; } break; case 'e': case 'E': { ++buf; Int32 exponent = readIntText(buf, end); x *= preciseExp10(exponent); run = false; break; } default: run = false; break; } ++buf; } if (negative) x = -x; return x; }