T
T
Ternick2020-09-21 22:50:35
C++ / C#
Ternick, 2020-09-21 22:50:35

How to decide to rewrite wtoi better?

THE CODE:

constexpr const int _wcslen(const wchar_t* test) {
  int len = -1;
  do {
    len++;
  } while (*test++ != L'\0');
  return len;
}

constexpr const int getIntFromWchar_t(wchar_t chr) {
  switch (chr)
  {
  case L'0':
    return 0;
  case L'1':
    return 1;
  case L'2':
    return 2;
  case L'3':
    return 3;
  case L'4':
    return 4;
  case L'5':
    return 5;
  case L'6':
    return 6;
  case L'7':
    return 7;
  case L'8':
    return 8;
  case L'9':
    return 9;
  default:
    return 10;
  }
}

constexpr const unsigned long long int pow(int a, int n) {
  if (a != 0) {
    unsigned long long int result = a;
    for (int i = 0; i < n - 1; i++) {
      result *= a;
    }
    return result;
  }
  else {
    if (n == 0) {
      return 1;
    }
    else {
      return 0;
    }
  }
}

constexpr const unsigned long long int wtoi(const wchar_t* str) {
  unsigned long long int result = 0;
  for (int i = 0; i != _wcslen(str); i++) {
    unsigned long long int p = pow(10, _wcslen(str) - i - 1);
    if (p == 0) {
      result += getIntFromWchar_t(str[i]);
    }
    else {
      result += getIntFromWchar_t(str[i]) * p;
    }
  }
  return result;
}

Everything would be fine if it weren't for this.
wtoi(L"35") // => 80

Actually, this is the question of why this happens, although in theory everything should work well :)
Any kind of advice on improving the code design is also accepted :)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
jcmvbkbc, 2020-09-22
@Ternick

constexpr const unsigned long long int wtoi(const wchar_t* str) {
  unsigned long long int result = 0;
  for (int i = 0; str[i]; i++) {
      int digit = getIntFromWchar_t(str[i]);
      if (digit < 0 || digit > 9)
           break;
      result = result * 10 + digit;
  }
  return result;
}

Usually they do something like this, this is a special case of Horner's scheme .
constexpr const int getIntFromWchar_t(wchar_t chr) {
  switch (chr)
  {
  case L'0':
    return 0;
  case L'1':
    return 1;
  case L'2':
    return 2;
  case L'3':
    return 3;
  case L'4':
    return 4;
  case L'5':
    return 5;
  case L'6':
    return 6;
  case L'7':
    return 7;
  case L'8':
    return 8;
  case L'9':
    return 9;
  default:
    return 10;
  }
}

Can be rewritten like this:
int getIntFromWchar_t(wchar_t chr) {
    return chr - L'0';
    static_assert(L'1' == L'0' + 1);
    static_assert(L'2' == L'1' + 1);
    static_assert(L'3' == L'2' + 1);
    static_assert(L'4' == L'3' + 1);
    static_assert(L'5' == L'4' + 1);
    static_assert(L'6' == L'5' + 1);
    static_assert(L'7' == L'6' + 1);
    static_assert(L'8' == L'7' + 1);
    static_assert(L'9' == L'8' + 1);
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question