Давайте рассмотрим половину задачи на мгновение - преобразование из строковой базы n в unsigned long, где n - мощность 2 (база 2 для двоичного и базового 16 для шестнадцатеричного).
Если ваш ввод является нормальным, то эта работа представляет собой не что иное, как сравнение, подобие, сдвиг и цифру. Если ваш вход не нормальный, ну, вот где он становится уродливым, не так ли? Выполнение преобразования сверхбыстрого не сложно. Сделать это хорошо при любых обстоятельствах - задача.
Итак, давайте предположим, что ваш вклад в здравом уме, то сердце вашего преобразования заключается в следующем:
unsigned long PowerOfTwoFromString(char *input, int shift)
{
unsigned long val = 0;
char upperLimit = 'a' + (1 << shift)
while (*input) {
char c = tolower(*input++);
unsigned long digit = (c > 'a' && c < upperLimit) ? c - 'a' + 10 : c - '0';
val = (val << shift) | digit;
}
return val;
}
#define UlongFromBinaryString(str) PowerOfTwoFromString(str, 1)
#define UlongFromHexString(str) PowerOfTwoFromString(str, 4)
Посмотрите, как легко это? И это приведет к сбою в нестандартных входах. Большая часть вашей работы будет идти навстречу твоему входу, а не производительности.
Теперь этот код использует преимущества двух сдвигов. Легко распространяться на основание 4, основание 8, основание 32 и т. Д. Он не будет работать на немодулях двух оснований. Для них ваша математика должна измениться. Вы получаете
val = (val * base) + digit
, что концептуально одинаково для этого набора операций. Умножение на базу будет эквивалентно сдвигу. Поэтому я скорее всего воспользуюсь полностью обычной рутиной. И санируйте код при дезинфекции входов. И в этот момент, strtoul, вероятно, ваш лучший выбор. Вот ссылка на a version strtoul. Почти вся работа связана с крайними условиями - это должно указывать на то, где вы должны сосредоточиться: правильный, устойчивый код. Экономия на использовании бит-сдвигов будет минимальной по сравнению с экономией, скажем, без сбоев при плохом вводе.
Вы первые два имени функции крайне неверны. Вы не возвращаете десятичное представление. Вы возвращаете unsigned long с неопределенным, непрозрачным (если вы не сделаете что-то конкретное по реализации) внутренним представлением. –
Что вы предлагаете именам функций? –
Конечно, эти функции не нужны с strtol в библиотеке c. – jmucchiello