Шестнадцатеричный и десятичный при двоичном преобразовании - PullRequest
1 голос
/ 23 июля 2011

Например, вот два способа установить целочисленную переменную (скажем, C ++):

int x = 0xFF;
int y = 255;

Какой оператор скомпилирует быстрее, чтобы установить действительные биты в целочисленное значение?

Отредактировано : * компиляция изменена с выполнения. Я предположил, что преобразование в двоичный файл было во время выполнения, но, похоже, во время компиляции, учитывая ответ @ muntoo

Ответы [ 2 ]

8 голосов
/ 23 июля 2011

Нет абсолютно никакой разницы во времени выполнения и, вероятно, нет разницы в скорости компиляции.

Добавлено в ответ на комментарий:
Вот что происходит.Компилятор имеет синтаксический анализатор, вероятно, с рекурсивным спуском, и в нижней части он вызывает лексер для получения токенов.В этом случае токен после = является числом, которое он может определить по первой цифре, поэтому он выглядит примерно так, где pc - указатель на текущий символ:

if (isdigit(*pc)){
  intpart = 0;
  if (pc[0]=='0' && pc[1]=='x'){
    pc += 2;
    while(ishexdigit(*pc)){
      intpart *= 16;
      if (isdigit(*pc)){
        intpart += (*pc - '0')
      }
      else {
        intpart += (tolower(*pc) - 'a' + 10);
      }
      pc++;
    }
  }
  else {
    while(isdigit(*pc)){
      intpart *= 10;
      intpart += (*pc - '0');
      pc++;
    }
    if (*pc == '.'){
      // ... handle fractional part
    }
  }
}

В любом случае, как вы можете видеть, это довольно узкий цикл, который выполняет isdigit или ishexdigit или tolower один или два раза для каждого символа числа, а также для умножения, вычитания и сложения.Предполагая, что эти функции встроены, мы говорим, возможно, 10-20 инструкций на символ.В шестнадцатеричном регистре может быть немного больше инструкций на символ, но десятичное число будет содержать несколько больше символов, поэтому трудно сказать a-priori , который должен быть быстрее.Это происходит только для общего числа таких целых чисел, которое у вас было достаточно энергии для ввода в ваш код, например, около 100. Если машина может выполнять, скажем, 10 ^ 8 инструкций в секунду, она может читать цифры со скоростью около10 ^ 7 в секунду, или около 100 наносекунд на символ, или 10 микросекунд для всех чисел в вашем файле, дают или принимают порядок величин.

Как только компилятор узнает, что это число, он просто становится частьюабстрактного синтаксического дерева, которое используется для генерации ассемблера.К тому времени тот факт, что он был шестнадцатеричным или десятичным, уже давно забыт.Все, что он знает, это двоичное целое число определенного значения, поэтому язык ассемблера будет идентичным.

3 голосов
/ 23 июля 2011

0xFF - это то же самое, что и 255, с точки зрения вашего компилятора.Оба будут генерировать точно такой же код.Ваш компилятор "преобразует" их оба в 11111111b.


Скорость компиляции зависит от компилятора и от того, как он компилируется.

Например, 0xFF можно определить как шестнадцатеричноечисло (игнорируя регулярные выражения, что является предпочтительным методом):

bool myishex(string sz)
{
    if(sz[0] == '0' && sz[1] == 'x')
    {
        for(size_t i = 2; i < sz.length(); ++i)
            if(!(sz[i] >= '0' && sz[i] <= '9') || !(sz[i] >= 'A' && sz[i] <= 'F') || !(sz[i] >= 'a' && sz[i] <= 'f'))
                return(false);
    }
    else
    {
        return(false);
    }

    return(true);
}

По сравнению с myisnum():

bool myisnum(string sz)
{
    for(size_t i = 0; i < sz.length(); ++i)
        if(!(sz[i] >= '0' && sz[i] <= '9'))
            return(false);

    return(true);
}

Ну, myisnum() - это , в общем быстрее myishex().(Вероятность A-F или a-f выше 0-9.)


Но преобразование из FF в двоичное число может быть быстрее медленнее 255.

int myhex2bin(string sz)
{
    int b = 0;

    sz = sz.substr(2); // Cut the "0x" out.

    for(size_t i = 0; i < sz.length(); ++i)
    {
        sz[i] = tolower(sz[i]);
        b += myhexdigit2dec(sz[i]) << ((sz.length() - (i + 1)) << 2);
    }

    return(b);
}

// Unsafe. Optimized for speed.
int myhexdigit2dec(char c)
{
    return(c < 'A' ? c - '0' : (c < 'a' ? c - 'A' + 10 : c - 'a' + 10));
}

Принимая во внимание, что вы не получаете сдвигов в двоичном или десятичном виде, но вы не получаете ни A-F, ни a-f ни.

int mydec2bin(string sz)
{
    int b = 0;
    int factor = 1;

    for(size_t i = sz.length(); i > 0; --i)
    {
        b += (sz[i - 1] - '0') * factor;
        factor *= 10;
    }

    return(b);    
}

Вывод: По-прежнему зависит от компилятора, но 255 на , вероятно, быстрее для компиляции.:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...