fastfloat/fast_float

fast_int

xelatihy opened this issue · 1 comments

It would be nice to have a fast string to integer/unsigned parser with similar performance. I suspect it is just a matter of wrapping internal functions with a from_chars-like API. But, without knowing the code well, it is as easy to cook together.

It would be nice to have a fast string to integer/unsigned parser with similar performance.

The reason it is not provided is that it is a far easier problem and I expect that the current system libraries solve this problem well.

Here are examples for 64-bit examples of highly efficient code...

Parsing unsigned 64-bit integers...

  const uint8_t *p = src;
  const uint8_t *const start_digits = p;
  uint64_t i = 0;
  while (parse_digit(*p, i)) { p++; }
  size_t digit_count = size_t(p - start_digits);
  if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; }
  if (digit_count == 20) {
    if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; }
  }
  return i;

Parsing signed 64-bit integers...

  bool negative = (*src == '-');
  const uint8_t *p = src + negative;
  const uint8_t *const start_digits = p;
  uint64_t i = 0;
  while (parse_digit(*p, i)) { p++; }
  size_t digit_count = size_t(p - start_digits);
  size_t longest_digit_count = 19;
  if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; }
  if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; }
  return negative ? (~i+1) : i;

We may use the following generic function...

template<typename I>
bool parse_digit(const uint8_t c, I &i) {
  const uint8_t digit = static_cast<uint8_t>(c - '0');
  if (digit > 9) {
    return false;
  }
  i = 10 * i + digit; // might overflow, we will handle the overflow later
  return true;
}

You may need to accommodate various bit width (8, 16, 32...) and then you want to handle hexadecimals and so forth.

Pull requests invited.