Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
non_grata
3 / 3 / 0
Регистрация: 07.10.2017
Сообщений: 18
1

Не понимаю представление шестнадцатеричных цифр соответствующим целым

19.10.2017, 23:49. Просмотров 943. Ответов 13
Метки нет (Все метки)

Добрый вечер, я диспетчер, как поется в одной забавной песне, но мне не до шуток. Товарищи, столкнулся с одним неприятным заданием по книге Брайана Кернигана "Язык программирования Си".
Собственно говоря, задание звучит так - Напишите функцию htol(s), которая преобразует последовательность шестнадцатеричных цифр, начинающуюся с 0х или 0Х, в соответствующее целое. Шестнадцатеричными цифрами являются символы 0…9, а…f, А…F.
Сначала подумал, что нужно перевести из 16-ной в 10-ую, но потом понял свою ошибку. Кто нибудь может по действиям разобрать такой пример - "0x12BA"? Не утруждайтесь (если кто-то захочет помочь) писать программы или же считать конечное число, просто объясните, пожалуйста, ход действия и, желательно, с пояснением, как для самых глупых)) Заранее спасибо!
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.10.2017, 23:49
Ответы с готовыми решениями:

Функция, которая преобразует строку шестнадцатеричных цифр
Ребят просьба помочь хоть с какой нибудь задачей. Задача 1. Написать и протестировать функцию ,...

Проверить, равняется ли X сумме факториалов своих шестнадцатеричных цифр
Мы только начали изучать си . Можете написать код не используя функции ?Буду премного благодарен

Ошибка -is not a valid integer value (не является допустимым целым значением), не понимаю в чем ошибка
//--------------------------------------------------------------------------- #include <vcl.h>...

Получить множество всех общих шестнадцатеричных цифр трех натуральных чисел А, В, С
Составить программу, получает множество всех общих шестнадцатеричных цифр трех натуральных чисел А...

Не понимаю представление чисел с плавающей запятой
Кто может, объясните как можно проще, что это такое. В вики написанно: дробная часть логарифма...

13
Catstail
Модератор
24270 / 12239 / 2206
Регистрация: 12.02.2012
Сообщений: 19,867
20.10.2017, 10:24 2
Лучший ответ Сообщение было отмечено non_grata как решение

Решение

1)Заводим переменную-аккумулятор acc и обнуляем ее.
2)Убеждаемся, что префикс "0x" на месте и пропускаем его
3)берем очередной символ остатка строки и получаем число d по принципу '0' -> 0, '1'->1,...,'a' или 'A' -> 10,... 'F'->15
4)вычисляем acc=acc*16+d
5)переходим к п. 3 пока строка не закончится
6)в acc результат
1
non_grata
3 / 3 / 0
Регистрация: 07.10.2017
Сообщений: 18
20.10.2017, 13:55  [ТС] 3
Спасибо, все стало более-менее понятно, но есть один нюанс: почему в п. 4 мы умножаем именно на 16?
0
Байт
Эксперт C
20302 / 12865 / 2690
Регистрация: 24.12.2010
Сообщений: 26,880
20.10.2017, 15:18 4
Цитата Сообщение от non_grata Посмотреть сообщение
почему в п. 4 мы умножаем именно на 16?
Дык, система счисления-то 16-ричная.
Вообще, что такое представление числа в b-ичной системе счисления вы знаете?

Добавлено через 3 минуты
Это представление в виде N = a0 + a1b1 + a2b2 + ...
("цифры" ai нумеруются справа ) То что написано будет числом .. a2a1a0
Немного изменим последовательность вычислений, и получим алгоритм из поста 2.
1
non_grata
3 / 3 / 0
Регистрация: 07.10.2017
Сообщений: 18
20.10.2017, 17:09  [ТС] 5
Что такое представление числа в b-ичной системе счисления я знаю, я не понимаю фразу - представление последовательности шестнадцатеричных цифр соответствующим целым(это же не является переводом из 16-ной системы в 10-ую)
0
likehood
984 / 828 / 396
Регистрация: 25.12.2016
Сообщений: 2,727
Завершенные тесты: 3
20.10.2017, 18:15 6
non_grata, грубо говоря, вам нужно реализовать свою версию функции atoi для 16-ричных чисел, то есть преобразовать строку char* в число int.
0
Байт
Эксперт C
20302 / 12865 / 2690
Регистрация: 24.12.2010
Сообщений: 26,880
20.10.2017, 19:03 7
Цитата Сообщение от non_grata Посмотреть сообщение
Что такое представление числа в b-ичной системе счисления я знаю, я не понимаю фразу - представление последовательности шестнадцатеричных цифр соответствующим целым
Значит, не знаете. Или просто не понимаете до конца.
Число - это такая штука, которая не зависит от представления. Оно есть само по себе. В памяти компьютера оно представлено, как правило, в виде последовательности единиц и нулей. Но нам (и ему) нет до этого никакого дела. Мы знаем, что если мы напишем int a, b, то в машине оно будет как-то представлено, так, что арифметические операции над a и b будут выполняться правильно. Но чтобы нам общаться с компьютером, надо как-то представлять эти числа. Можно и по-римски. Мы, увы, понимаем только последовательности знаков. Каким образом, по каким правилам эти последовательности составляются - дело договора.
Вот так в двух словах.
2
non_grata
3 / 3 / 0
Регистрация: 07.10.2017
Сообщений: 18
20.10.2017, 20:32  [ТС] 8
Если я так напишу, это тоже будет правильно?
C
1
2
3
4
5
6
7
8
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;
0
likehood
984 / 828 / 396
Регистрация: 25.12.2016
Сообщений: 2,727
Завершенные тесты: 3
20.10.2017, 21:49 9
non_grata, напишите программу целиком и запустите её. Без этого вы никогда не узнаете правильная она или нет.

P.S.: s.length() - это C++, а здесь раздел С.
1
non_grata
3 / 3 / 0
Регистрация: 07.10.2017
Сообщений: 18
20.10.2017, 22:09  [ТС] 10
Прошу прощения у всех, чье время я потратил. Спасибо за помощь, благодаря вам, я разобрался.
1
Байт
20.10.2017, 22:16
  #11

Не по теме:

Цитата Сообщение от non_grata Посмотреть сообщение
Прошу прощения у всех, чье время я потратил
Ценим вашу вежливость и воспитанность:)
Но извинений в данном случае не требуется. Ведь никто не заставлял нас это время тратить, верно? Значит, это было нужно нам самим. Из доброты душевной, для самоутверждения, как способ проведения досуга - это в конце концов неважно...:)

0
tmpValue
41 / 74 / 15
Регистрация: 04.10.2017
Сообщений: 284
21.10.2017, 01:41 12
Цитата Сообщение от non_grata Посмотреть сообщение
Если я так напишу, это тоже будет правильно?
Только в случае полной уверенности в том что входные данные upcase. Ибо для символов 'A' и 'a' коды разные. Вот более совершенный вариант. Не учитывает переполнение.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
#include <stdint.h>
#include <ctype.h>
 
uint32_t
foo (const uint8_t * s)
{
  uint32_t result = 0;
  uint8_t checkout = 0;
  const uint8_t * ptr = s;
 
  // проверяем наличие первых символов "0x" или "0X"
  checkout = ptr != NULL &&
    ptr[0] == '0' &&
    ptr + 1 != NULL &&
    (ptr[1] == 'x' || ptr[1] == 'X');
 
  if (checkout) {
    ptr = s + 2;
 
    while (*ptr) {
      result <<= 4; // сдвиг влево на 4 бита. 4 бита необходимы для одной 16й цифры
      if (isdigit(*ptr)) // если символ в диапазоне [0,9]
    result += *ptr - '0'; // отнять от символа код символа '0'
      else if (isalpha(*ptr)) { // если символ есть буква алфавита
    // вычитаем код символа в зависимости от регистра исходного символа
    // так 'B' - 'A' == 1, 'c' - 'a' == 2, etc
    int32_t t = isupper(*ptr) ? *ptr - 'A' : *ptr - 'a';
    // no comment
    t += 10;
    // если число в диапазоне, то прибавляем к результату
    if (t <= 0xF && t >= 0xA)
      result += (uint32_t)t;
    else { // иначе обрываем работу и возвращаем 0
      result = 0;
      break;
    }
      }
      ptr++;
    }
  }
 
  return result;
}
 
 
int
main (int argc, char ** argv)
{
  unsigned char s[] = "0x78aBCdEF";
  fprintf(stdout, "%X\n", foo(s));
  return 0;
}
1
non_grata
3 / 3 / 0
Регистрация: 07.10.2017
Сообщений: 18
21.10.2017, 15:21  [ТС] 13
Ну это уже высший пилотаж, но все равно спасибо)
0
COKPOWEHEU
1263 / 908 / 210
Регистрация: 09.09.2017
Сообщений: 3,834
21.10.2017, 18:00 14
Цитата Сообщение от tmpValue Посмотреть сообщение
int32_t t = isupper(*ptr) ? *ptr - 'A' : *ptr - 'a';
// no comment
t += 10;
так проще и нагляднее
int32_t t = tolower(*ptr)-'a'+0x0A;
1
21.10.2017, 18:00
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.10.2017, 18:00

Создать программу кторое получает множество всех общих шестнадцатеричных цифр, трех наутральных чисел А,В,С
Помогите написать исходник , с использованием множества! Создать программу кторое получает...

Написать и протестировать функцию, которая преобразует строку шестнадцатеричных цифр в эквивалентное ей целое десятичное число
Написать и протестировать функцию, которая преобразует строку шестнадцатеричных цифр в...

По введенным целым числом М распечатать все трехзначные десятичные числа, сумма цифр которых равна M
По введенным целым числом М распечатать все трехзначные десятичные числа, сумма цифр которых равна...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru