Как я могу безопасно и быстро извлечь цифры из int? - PullRequest
3 голосов
/ 31 августа 2010

В настоящее время у нас есть некоторый код для извлечения цифр из int, но мне нужно преобразовать его в платформу без snprintf, и я боюсь переполнения буфера.Я начал писать свой собственный портативный (и оптимизированный) snprintf, но мне сказали спросить здесь на случай, если у кого-то возникнет идея получше.

int extract_op(int instruction)
{ 
    char buffer[OP_LEN+1];
    snprintf(buffer, sizeof(buffer), "%0*u", OP_LEN, instruction);
    return (buffer[1] - 48) * 10 + buffer[0] - 48;
}

Мы используем строки C, потому что скорость очень важна.

Ответы [ 5 ]

7 голосов
/ 31 августа 2010

Для этого вам не нужно формировать instruction в массив символов; вам просто нужно сохранить «две верхние цифры» следующим образом:

int extract_op(unsigned int instruction)
{
    int first = 0;
    int second = 0;
    while(instruction) {
        second = first;
        first = instruction % 10;
        instruction /= 10;
    }
    return first + 10 * second;
}

Я думаю, что выражение в return неверно, но оно имитирует то, что вы делаете: десятикратное второе число плюс первое.

Я подозреваю, что скорость может быть даже лучше, чем та, которую вы получаете сейчас, но, конечно, вам нужно измерить на вашей конкретной платформе и компиляторе.

2 голосов
/ 31 августа 2010

Использование sprintf должно быть хорошо. sizeof type * 3 * CHAR_BIT / 8 + 2 - достаточно большой буфер для печати целого числа типа type. Вы можете упростить это выражение, если предположите, что CHAR_BIT равно 8 или если вас интересуют только неподписанные форматы. Основная идея заключается в том, что каждый байт содержит не более 3 цифр в десятичной (или восьмеричной) форме, и вам нужно место для знака и нулевого завершения.

1 голос
/ 31 августа 2010

Пока есть один ответ, который меняет местами последние две цифры, и один, который меняет местами первые две ... мне кажется, что "%0*u", OP_LEN принудительно выводит вывод на определенную ширину, и значение извлеченных цифр предопределяется с помощью OP_LEN.

Предполагая, что OP_LEN является макросом, мы можем получить 10 ^ (OP_LEN-2) с

#define DIVISOR ( (int) ( 1.e ## OP_LEN * 0.01 ) )

Затем, аналогично ответу @ zneak,

int extract_op( int instruction )
{
    instruction /= DIVISOR;
    int tens = (instruction / 10) % 10;
    int units = instruction % 10;
    return units * 10 + tens;
}

#undef DIVISOR
0 голосов
/ 31 августа 2010

должно работать также для 0 и <0. </p>

int extract_op( int instruction )
{
  int numd = 1;
  while( instruction /= 10 )
    ++numd;
  return numd;
}
0 голосов
/ 31 августа 2010

U может хранить цифру, которую вы получаете в массив.ЭТО ОДИН БЫЛ КОДЕКС, ПОЯСНЕННЫЙ АЛЕКСОМ.здесь я добавляю некоторые переменные.

int a[5];

int extract_op(unsigned int instruction)
{
int i=0;    
int first = 0;
    int second = 0;
    while(instruction) {
        second = first;
        first = instruction % 10;
        instruction /= 10;
    }
    a[i]=first;
}

Это то, что будет работать для всех целых чисел будет иметь максимум 5 цифрНо все же, если вы хотите взять динамический массив, вы можете использовать список ссылок

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