Di git подсчет л oop КПД - PullRequest
       12

Di git подсчет л oop КПД

0 голосов
/ 21 марта 2020

Я хочу реализовать функцию, аналогичную atoi, которая бы устанавливала глобальную переменную обработки ошибок, если число цифр превышает определенное число, где обычное количество цифр в диапазоне 1-8. Я хочу знать, какая реализация быстрее satoi1 vs satoi2

    int satoi1(char **ptr, int maxdigits)
    {
      char *s = *ptr;
      int cnt = 0
      int val = 0;
      while(isdigit(*s))
        {
          val = val *10 + (*s - '0');
          s++;
          cnt++;
        }
        if(cnt > maxdigits)
         errnum = ERR_TOO_MNY_DIG;
        *ptr = s;
        return val;
    }



    int satoi2(char **ptr, int maxdigits)
    {
      char *s = *ptr;
      char *s1 = s;
      int val = 0;
      while(isdigit(*s))
        {
          val = val *10 + (*s - '0');
        }
        if((s - s1) > maxdigits)
         errnum = ERR_TOO_MNY_DIG;
        *ptr = s;
        return val;
    } 

Ответы [ 2 ]

0 голосов
/ 21 марта 2020

Если пользователь вводит миллион цифр подряд, l oop (любая версия) не остановится на 8-м (или любом другом) di git, что может привести к переполнению арифметического c в вычислениях.

Попробуйте

while ((inputdigits < maxdigits) && isdigit((unsigned char)*s)) {
    /* .... */
}
0 голосов
/ 21 марта 2020

Я хочу знать, какая реализация быстрее satoi1 vs satoi2

Как и в случае таких микрооптимизаций, часто теряется фокус на правильной функциональности. Вторая функция имеет бесконечное значение l oop, поэтому первая является самой быстрой. @ Том Карзес

С исправленным satoi2() у него больше шансов быть быстрее с меньшим значением l oop, но нужно быть уверенным в профиле.

int satoi2_corrected(char **ptr, int maxdigits) {
  char *s = *ptr;
  char *s1 = s;
  int val = 0;
  while(isdigit(*s)) {
    val = val *10 + (*s - '0');
    s++; // Missing is OP's code
  }
  if((s - s1) > maxdigits)
     errnum = ERR_TOO_MNY_DIG;
  *ptr = s;
  return val;
}

Неподвижный код имеет неопределенное поведение (UB).

  // Avoid `is...(negative value)
  /// while(isdigit(*s)) {
  while(isdigit((unsigned char) *s)) {

Используйте unsigned, чтобы избежать UB переполнения int

  //int val = 0;
  unsigned val = 0;
  while(isdigit((unsigned char) *s)) {
    val = val*10 + (*s - '0');
    s++;
  }

OP прокомментировал "Меня не волнует возвращаемое значение, так как действительное количество цифр число цифр <= 8 в любом случае". Если <code>val не требуется вообще, вычисление val не требуется.

  while(isdigit((unsigned char) *s)) {
    s++;
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...