Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Общие вопросы по программированию, компьютерный форум
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.12.2022, 16:06   #1
dstrx
Новичок
Джуниор
 
Регистрация: 18.12.2022
Сообщений: 2
По умолчанию Преобразование строки, состоящей из шестнадцатеричного числа

Код:
int Num(string s){
    int result = 0;
    for (int i = 0; i < s.length(); ++i){
        if (s[i] >= '0' && s[i] <= '9')
            result = 16 * result + s[i] - '0';
        else
            result = 16 * result + s[i] - 'A' + 10;
    }
    return result;
}
Объясните, пожалуйста, каким образом эта программа преобразует шестнадцатеричную строку в шестнадцатеричное число.
dstrx вне форума Ответить с цитированием
Старый 18.12.2022, 17:30   #2
ViktorR
Старожил
 
Регистрация: 23.10.2010
Сообщений: 2,309
По умолчанию

По приведённому алгоритму:
Шестнадцатеричное представление числа преобразуется в формат BCD.
В этом формате цифры числа занимают 4-бита.

Если символ из набора символов от '0' до '9', то результат умножается на 16.
Умножение - это сдвиг влево. В данном случае - на 4-е бита.
Из кода символа вычитается код символа '0'. Это соответствует двоичному представлению цифры.
Полученное значение добавляется в результат.

Иначе:
результат так же сдвигается влево на 4-е бита, но из кода символа вычитается код символа 'A'.
Это будет соответствует цифрам 0, 1, 2, 3, 4, 5 для символов 'A', 'B', 'C', 'D', 'E', 'F'.
Добавляем 10-у и сохраняем в result.

Пример:
Код:
s = 13AC
Первый шаг: '1' - '0' --> 0001;                         result = 0001
Второй шаг: '3' - '0' --> 0011;                         result = 00010011
Третий шаг: 'A' --> 10; 'A' - 'A' + 10 = 10 --> 1010    result = 000100111010
Четвёртый шаг: 'C' --> 12; 'C' - 'A' + 10 = 12 --> 1100 result = 0001001110101100
PS: В примере не показал сам сдвиг, но думаю, что понять можно, что перед добавлением в result делается сдвиг.
Как-то так, ...
ViktorR вне форума Ответить с цитированием
Старый 18.12.2022, 17:37   #3
Cuprum5
Форумчанин
 
Регистрация: 09.05.2017
Сообщений: 735
По умолчанию

Проход циклом по всем символам строки. Для одного символа: условие, если число от 0 до 9(включительно), то прибавляем его к результату предварительно сдвинув результат влево или умножить на 16(Base, база) -'0' - это преобразование из символа в число. Если число имеет букву(ветка else), то преобразуем ее в число.
Cuprum5 вне форума Ответить с цитированием
Старый 18.12.2022, 17:45   #4
Cuprum5
Форумчанин
 
Регистрация: 09.05.2017
Сообщений: 735
По умолчанию

Цитата:
Сообщение от ViktorR Посмотреть сообщение
Шестнадцатеричное представление числа преобразуется в формат BCD.
В этом формате цифры числа занимают 4-бита.
- BCD это другое, у него байтом кодируется.
Cuprum5 вне форума Ответить с цитированием
Старый 18.12.2022, 17:45   #5
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Цитата:
Сообщение от ViktorR Посмотреть сообщение
Шестнадцатеричное представление числа преобразуется в формат BCD.
А причем тут BCD. BCD это двоично десятичное кодирование, когда двоичное число в шестнадцатеричном представлении понимается как десятичное.
Тут просто перевод значений одного диапазона (ASCII кодов) в другой диапазон ([0 .. 15]). Т.к. в ASCII представлении между кодами 0,1,2,3,4,5,6,7,8,9 и A,B,C,D,E,F есть разрыв, то и обрабатываются они отдельно. Из-за этого и нужен if.
Код:
                         ...
            +----------> '0' = 0x30 = 48
            |+---------> '1' = 0x31
            ||+--------> '2' = ...
 0 = 0000 <-+||+-------> '3'
 1 = 0001 <--+||+------> '4'
 2 = 0010 <---+||+-----> '5'
 3 = 0011 <----+||+----> '6'
 4 = 0100 <-----+||+---> '7'
 5 = 0101 <------+||+--> '8'
 6 = 0110 <-------+||+-> '9'
 7 = 0111 <--------+||    .
 8 = 1000 <---------+|    .
 9 = 1001 <----------+    .
10 = 1010 <-----------+   .
11 = 1011 <----------+|   .
12 = 1100 <---------+||   .
13 = 1101 <--------+|||   .
14 = 1110 <-------+|||+> 'A' = 0x41 = 65
15 = 1111 <------+|||+#> 'B' = 0x42
                 |||+##> 'C' = ...
                 ||+###> 'D'
                 |+####> 'E'
                 +#####> 'F'
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 ||||||   .
                 |||||+> 'a' = 0x61 = 97
                 ||||+-> 'b' = 0x62
                 |||+--> 'c' = ...
                 ||+---> 'd'
                 |+----> 'e'
                 +-----> 'f'
                         ...
Вот так надо сопоставлять цифры с символами
Код:
s = 13AC
Первый шаг: '1' - '0' --> 0001;                         result = 0000`0000`0000`0001
Второй шаг: '3' - '0' --> 0011;                         result = 0000`0000`0001`0011
Третий шаг: 'A' --> 10; 'A' - 'A' + 10 = 10 --> 1010    result = 0000`0001`0011`1010
Четвёртый шаг: 'C' --> 12; 'C' - 'A' + 10 = 12 --> 1100 result = 0001`0011`1010`1100
Длина в битах result не изменяется. В начале просто не напечатаны незначащие 0.

Последний раз редактировалось macomics; 18.12.2022 в 18:17.
macomics вне форума Ответить с цитированием
Старый 19.12.2022, 11:04   #6
ViktorR
Старожил
 
Регистрация: 23.10.2010
Сообщений: 2,309
По умолчанию

По поводу BCD слегка махнул.
В том смысле, что исходно BCD -формат используется для кодирования десятичных цифр числа.
В данном случае - это расширенная его форма, когда и шестнадцатеричная цифра числа упаковывается в BCD.

Cuprum5
Цитата:
- BCD это другое, у него байтом кодируется.
Это у кого "у него"?
BCD - это формат для упаковки символьного представления чисел.
При этом на цифру тратится один нибл (4-е бита), а в байте хранятся две цифры числа.

macomics - Спасибо с схему. Самому было лень такое рисовать.
Вместе с тем ваша схема скрывает тот факт, что символ занимает байт:
'5' это 00110101, а не 0101.
Вычитая символ нуля ('0' --> 00110000) или символ 'A' --> 01000001 из символа цифры, мы обнуляем старший нибл.
Это позволяет выполнить следующие шаги:
- сдвиг результата, полученного на предыдущем шаге влево на 4-е бита;
- сложение (добавление 4-х битов в результат).

Цитата:
Длина в битах result не изменяется. В начале просто не напечатаны незначащие 0.
Согласен, поскольку у resul тип int, а это два байта. Переменная инициализирована нулём.
Как-то так, ...
ViktorR вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Паскаль: является ли введенная с клавиатуры последовательность символов записью двоичного или шестнадцатеричного числа Студент ММИ Помощь студентам 12 14.11.2014 14:22
Преобразование часов в числа, а так же преобразование время PeMeHb Microsoft Office Excel 5 19.10.2014 17:04
Ввести строку, содержащую цифры. Определить является ли она записью шестнадцатеричного числа. Roman1295 Паскаль, Turbo Pascal, PascalABC.NET 10 24.12.2012 22:52
Из строки, состоящей из букв, цифр, запятых, точек, знаков + и – , выделить подстроку, задающую вещественное число с фиксированной manhant23 C++ Builder 1 27.01.2012 23:35
преобразование числа в hex fize Помощь студентам 20 27.11.2009 19:45