Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.70/64: Рейтинг темы: голосов - 64, средняя оценка - 4.70
79 / 25 / 13
Регистрация: 01.06.2019
Сообщений: 574
1

Рекурсивная функция перевода числа в двоичную, восьмеричную и шестнадцатеричную системы

22.08.2019, 21:18. Показов 12241. Ответов 20
Метки нет (Все метки)

Пользователь вводит число в десятичной системе счисления. Перевести его в двоичную, восьмеричную и шестнадцатеричную
системы. (не забываем заменять числа на ABCDEF в 16-ричной системе)

Сделать с помощью рекурсии
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.08.2019, 21:18
Ответы с готовыми решениями:

Рекурсивная процедура перевода числа из десятичной системы счисления в двоичную
3) Написать рекурсивную процедуру перевода нату¬рального числа из десятичной системы счисления в...

Перевод чисел из десятичной системы счисления в двоичную, восьмеричную, шестнадцатеричную
напишите код программы для проверки перевода чисел из десятичной системы счисления в...

Рекурсивная функция перевода натурального числа из десятичной системы счисления
Хелпаните с задачей! Написать рекурсивную процедуру перевода натурального числа из десятич- ной...

Программа перевода числа из 10ой системы в двоичную
Сам код: #include <iostream> using namespace std; int main() { long int i; int value; cout...

20
567 / 406 / 132
Регистрация: 22.11.2017
Сообщений: 1,054
22.08.2019, 23:07 2
Rudman132, привет!
Цитата Сообщение от Rudman132 Посмотреть сообщение
Перевести его в двоичную, восьмеричную и шестнадцатеричную
системы
Перевод в двоичную через рекурсию сделан, а остальное нет.
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
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
 
void dec_to_bin(size_t dec, std::vector<bool>& bin)
{
    if (dec)
    {
        bin.push_back(dec & 1u);
        dec_to_bin(dec >> 1u, bin);
    }
    else
        std::reverse(std::begin(bin), std::end(bin));
}
 
int main()
{
    size_t num;
    std::cin >> num;
    std::vector<bool> bin;
    dec_to_bin(num, bin);
    std::copy(std::begin(bin), std::end(bin), std::ostream_iterator<bool>(std::cout));
    std::cout << "\n";
    std::cout << std::oct << num << "\n";
    std::cout << std::hex << std::uppercase << num << "\n";
 
    return 0;
}
1
Миниатюры
Рекурсивная функция перевода числа в двоичную, восьмеричную и шестнадцатеричную системы  
221 / 148 / 79
Регистрация: 14.03.2016
Сообщений: 459
22.08.2019, 23:33 3
Можно и в С-шные строки переделать, думаю, так чуть быстрей будет, если нельзя использовать флаги вывода hex и oct.
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
#include <iostream>
using namespace std;
 
int progEnd(int code = 0) { std::cout << "\nEND\n"; system("pause>nul"); return code; }
 
//переводит числа от 0 до 9 в соотв. символы. Числа более 9 - в символы A, B и т.д.
inline constexpr char BaseChar(int value) { return ( value > 9 ? 'A' + value - 10 : '0' + value ); }
 
//сама функция | после окончания работы возвращает указатель на конец строки, на нулевой байт ('\0')
char* toNBaseC(char* str, int value, int base) {
    if(value < base) *str = BaseChar(value);
    else {
        str = toNBaseC(str, value / base, base);
        *str = BaseChar(value % base);
    }
    return str + 1;
}
 
//возвращает длину числа в переданной системе счисления
inline constexpr int getNumLength(int value, int base) { return ( value ? int( log10( (value < 0) ? abs(value) : value ) / log10(base) ) + 1 : 1 ); }
 
int main() {
    int value = 0x2543; //число (9539 в десятичной)
    int base = 16; //сис. счис, в которую переводим
 
    char *str = new char[getNumLength(value, base) + 1]; //выделяем память под строку
    
    //конвертируем | ставим последний байт в 0
    *toNBaseC(str, value, base) = '\0';//можно обернуть в др. функцию, чтобы не забывать про последний символ
 
    cout << str << endl;
 
    //не забываем про память
    delete[] str;
    return progEnd(0);
}
2
79 / 25 / 13
Регистрация: 01.06.2019
Сообщений: 574
23.08.2019, 00:03  [ТС] 4
Цитата Сообщение от SomniPhobia Посмотреть сообщение
Перевод в двоичную через рекурсию сделан, а остальное нет.
А можно как то проще, без алгоритма вектора итератора ?, не учили еще

Добавлено через 8 минут
Перевод хотя бы в одну из систем, но проще
0
813 / 500 / 211
Регистрация: 19.01.2019
Сообщений: 1,196
23.08.2019, 01:15 5
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void conv(uint32_t dec, size_t base, std::string* str) {
    if (dec) {
        conv(dec / base, base, str);
        size_t res = dec % base;
        str->append(1, res > 9 ? 'A' + res - 10 : '0' + res);
    }
}
 
std::string conv(uint32_t dec, size_t base) {
    if (!dec) {
        return "0";
    }
    if (base > 36) {
        return "err";
    }
    std::string res;
    conv(dec, base, &res);
    return res;
}
main

C++
1
2
3
4
5
6
    std::cout << conv(0, 2) << '\n';
    std::cout << conv(10, 2) << '\n';
    std::cout << conv(63, 8) << '\n';
    std::cout << conv(255, 16) << '\n';
    std::cout << conv(1295, 36) << '\n';
    std::cout << conv(INTMAX_MAX, 2) << '\n';
1
Модератор
Эксперт С++
11087 / 9139 / 5491
Регистрация: 18.12.2011
Сообщений: 24,427
23.08.2019, 06:16 6
nalbe666, Cortas, SomniPhobia,
Все бы хорошо, однако:
Цитата Сообщение от Rudman132 Посмотреть сообщение
Пользователь вводит число в десятичной системе счисления
Т.е. на входе функции должна быть строка содержащая число в 10 системе счисления, а не int....
0
813 / 500 / 211
Регистрация: 19.01.2019
Сообщений: 1,196
23.08.2019, 10:26 7
zss, почему именно строка и чем плох int?
0
221 / 148 / 79
Регистрация: 14.03.2016
Сообщений: 459
23.08.2019, 10:37 8
zss, согласен с nalbe666, зачем строку? Нет, можно, конечно, но зачем? Навряд ли вы захотим использовать модификаторы ввода др. систем счисления. Математические операции ещё никто не отменял, и в таком случае нужно либо заморочиться со строчной арифметикой, либо перевести строку в int и там уже конвектировать, либо что-то ещё более хитрое.
Может мы вас неправильно поняли?
0
Модератор
Эксперт С++
11087 / 9139 / 5491
Регистрация: 18.12.2011
Сообщений: 24,427
23.08.2019, 11:01 9
По условию задачи задается число в ДЕСЯТИЧНОЙ системе счисления, а не в двоичной.
Вы же число уже представленное в двоичной системе счисления преобразуете в строку содержащую коды битов этого исходного двоичного числа.
А перевод из десятичной в двоичную у Вас выполняет
C++
1
istream& operator>>(istream&,int&);
0
567 / 406 / 132
Регистрация: 22.11.2017
Сообщений: 1,054
23.08.2019, 11:56 10
На вид коды нормальные. zss, соглашусь, что под капотом так оно и есть.
А со строкой тогда как делать?
1. Длинную арифметику писать
или
2. Задействовать контейнер bitset
или
?
0
813 / 500 / 211
Регистрация: 19.01.2019
Сообщений: 1,196
23.08.2019, 12:15 11
zss, В начале мы вводим число в консоль. Оно попадает в буфер как набор чаров, представляющих число в десятичной системе. Это оно? А затем уже забираем его оператором как int для упрощения дальнейших манипуляций и универсальности.
0
Модератор
Эксперт С++
11087 / 9139 / 5491
Регистрация: 18.12.2011
Сообщений: 24,427
23.08.2019, 13:36 12
Цитата Сообщение от nalbe666 Посмотреть сообщение
забираем его оператором как int
Это как раз и есть преобразование десятичного представления в двоичное.

Добавлено через 2 минуты
Цитата Сообщение от SomniPhobia Посмотреть сообщение
А со строкой тогда как делать?
Сделать свое преобразование в int (получится аналогично тому, что уже тут написано, только наоборот, каждый раз множить на 10).
0
567 / 406 / 132
Регистрация: 22.11.2017
Сообщений: 1,054
23.08.2019, 15:53 13
Лучший ответ Сообщение было отмечено Rudman132 как решение

Решение

zss, Rudman132, я написал универсальный код.
Программа принимает на входе число в виде строки. Изменяя значение переменной radix_input, можно назначить любую систему счисления на приём числа. То есть, принимается число в виде строки в системе счисления с основанием radix_input. Приводится в десятичный вид и сохраняется в переменную типа unsigned long long (ull).
Затем вызывается рекурсивная функция, которая переводит в нужные системы счисления из списка bases_convert. Всё рекурсивно при переводе из десятичной в указанную систему. Затем происходит подготовка к выводу (функцией number_to_string()) и сам вывод результата на консоль.
Для компиляции кода нужна поддержка C++17.

Кликните здесь для просмотра всего текста

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <optional>
#include <numeric>
#include <cmath>
#include <iomanip>
 
using uchar = unsigned char;
using ull = unsigned long long;
 
std::optional<std::vector<uchar>> transform_letters_to_digits(const std::string& line);
bool checking_number_system(const std::vector<uchar>& digits, uchar radix);
ull constructing_number_dec_from_digits(const std::vector<uchar>& digits, uchar radix);
std::optional<ull> string_to_ull(const std::string& line, uchar radix);
void dec_to_radix(ull num, uchar radix, std::vector<uchar>& dump);
std::string number_to_string(std::vector<uchar>& number);
 
int main()
{
    setlocale(LC_ALL, "Rus");
    const uchar radix_input = 10u;
    const std::initializer_list<uchar> bases_convert { 2u, 8u, 16u };
    
    std::cout << "Введите число в системе счисления с онованием "
        << static_cast<unsigned short>(radix_input) << "\n";
    std::string input;
    std::getline(std::cin, input);
    
    std::optional<ull> num_dec_opt = string_to_ull(input, radix_input);
    if (!num_dec_opt)
        return 1;
 
    for (auto radix : bases_convert)
    {
        std::vector<uchar> given_num;
        dec_to_radix(*num_dec_opt, radix, given_num);
        std::string num_str = number_to_string(given_num);
        std::cout << "Число " << input
            << " в системе счисления с основанием " << std::setw(3u) << static_cast<unsigned short>(radix)
            << " " << num_str << "\n";
    }
 
    return 0;
}
 
std::optional<std::vector<uchar>> transform_letters_to_digits(const std::string& line)
{
    std::vector<uchar> digits(line.length());
    size_t idx = 0u;
    for (auto c : line)
    {
        if (c >= '0' && c <= '9')
            digits[idx++] = c - '0';
        else
        {
            char cup = std::toupper(c);
            if (cup >= 'A' && cup <= 'Z')
                digits[idx++] = c - 'A' + 10u;
            else
                return {};
        }
    }
    return digits;
}
 
bool checking_number_system(const std::vector<uchar>& digits, uchar radix)
{
    for (auto d : digits)
        if (d >= radix)
            return false;
    return true;
}
 
ull constructing_number_dec_from_digits(const std::vector<uchar>& digits, uchar radix)
{
    ull num = 0u;
    uchar count_digits = digits.size();
    for (auto d : digits)
        num += d * std::pow(radix, --count_digits);
    return num;
}
 
std::optional<ull> string_to_ull(const std::string& line, uchar radix)
{
    std::optional<std::vector<uchar>> digits = transform_letters_to_digits(line);
    if (!digits)
    {
        std::cout << "Ошибка. Обнаружен некорректный символ\n";
        return {};
    }
    if (!checking_number_system(*digits, radix))
    {
        std::cout << "Ошибка. Обнаружена цифра превосходящая возможные цифры требуемой системы счисления\n";
        return {};
    }
    return constructing_number_dec_from_digits(*digits, radix);
}
 
void dec_to_radix(ull num, uchar radix, std::vector<uchar>& dump)
{
    if (num)
    {
        dump.push_back(num % radix);
        dec_to_radix(num / radix, radix, dump);
    }
    else
        std::reverse(std::begin(dump), std::end(dump));
}
 
std::string number_to_string(std::vector<uchar>& number)
{
    std::string dump(number.size(), 'A');
    size_t idx = 0u;
    for (auto digit : number)
    {
        if (digit >= 0u && digit <= 9u)
            dump[idx++] = digit + '0';
        if (digit >= 10u && digit <= 35u)
            dump[idx++] = digit - 10 + 'A';
    }
    return dump;
}
1
Миниатюры
Рекурсивная функция перевода числа в двоичную, восьмеричную и шестнадцатеричную системы  
567 / 406 / 132
Регистрация: 22.11.2017
Сообщений: 1,054
23.08.2019, 16:05 14
У меня в строке 60 ошибка.
Вместо
C++
1
digits[idx++] = c - 'A' + 10u;
Нужно
C++
1
digits[idx++] = cup - 'A' + 10u;
1
79 / 25 / 13
Регистрация: 01.06.2019
Сообщений: 574
23.08.2019, 16:05  [ТС] 15
Цитата Сообщение от SomniPhobia Посмотреть сообщение
написал универсальный код.
Перебрал ваш код и написал под себя:

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
 #include<iostream>
using namespace std;
 
void convert (int input, int result, int d=1)
{
    cin >> input;
    while (input)
    {
        result += (input % 2) * d;
        input = input / 2;
        d = d * 10; 
    }
    cout << "Двоичная система: " << result;
}
 
int main()
{
    setlocale(LC_ALL, "rus");
    
    int result = 0, input = 0;
    cout << "Введите число: ";
    convert(input,result);
 
    cout << endl;
    system("pause");
}
Не подскажите формулы перевода в восьмеричную и шестнадцатеричную системы
1
567 / 406 / 132
Регистрация: 22.11.2017
Сообщений: 1,054
23.08.2019, 16:12 16
Цитата Сообщение от Rudman132 Посмотреть сообщение
void convert (int input, int result, int d=1)
{
* * cin >> input;
Получается у тебя, что каждый проход рекурсии идёт запрос числа?
Число нужно запросить один раз, а при рекурсии стачивать его функцией.
Цитата Сообщение от Rudman132 Посмотреть сообщение
Не подскажите формулы перевода в восьмеричную и шестнадцатеричную системы
Формула для перевода из десятичной в любую всегда одна:
A1:
Если пришедшее в функцию число x равно нулю,
то завершить функцию,
иначе
Делим число x на основание системы (8 или 16 или 2 и т. д.).
Остаток от деления кладём в контейнер.
Частное передаём снова на обработку в A1 в качестве нового значения x.
1
79 / 25 / 13
Регистрация: 01.06.2019
Сообщений: 574
23.08.2019, 16:18  [ТС] 17
Цитата Сообщение от SomniPhobia Посмотреть сообщение
Число нужно запросить один раз, а при рекурсии стачивать его функцией.
вот так
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
#include<iostream>
using namespace std;
 
void convert (int input, int result, int d=1)
{
 
    while (input)
    {
        result += (input % 2) * d;
        input = input / 2;
        d = d * 10; 
    }
    cout << "Двоичная система: " << result;
}
 
int main()
{
    setlocale(LC_ALL, "rus");
    
    int result = 0, input = 0;
    cout << "Введите число: ";
    cin >> input;
    convert(input,result);
 
    cout << endl;
    system("pause");
}
0
567 / 406 / 132
Регистрация: 22.11.2017
Сообщений: 1,054
23.08.2019, 16:21 18
Цитата Сообщение от Rudman132 Посмотреть сообщение
вот так
Это получается без рекурсии.
0
79 / 25 / 13
Регистрация: 01.06.2019
Сообщений: 574
23.08.2019, 16:21  [ТС] 19
Цитата Сообщение от SomniPhobia Посмотреть сообщение
Это получается без рекурсии.
а как с рекурсией сделать?
0
567 / 406 / 132
Регистрация: 22.11.2017
Сообщений: 1,054
23.08.2019, 17:01 20
Лучший ответ Сообщение было отмечено Rudman132 как решение

Решение

Цитата Сообщение от Rudman132 Посмотреть сообщение
а как с рекурсией сделать?
Чтобы было с рекурсией нужно:
1. Убрать while
2. Добавить if, у котрого по первой ветке идёт:
взятие остатка и вывод его на консоль,
рекурсивный вызов функции для дальнейшего разложения с передачей ей частного
return convert (...);

Добавлено через 6 минут
Цитата Сообщение от Rudman132 Посмотреть сообщение
а как с рекурсией сделать?
Так? Только результат будет задом на перёд записан.
C++
1
2
3
4
5
6
7
8
void convert(int input)
{
    if (input)
    {
        cout << input % 2u;
        convert(input / 2u);
    }
}
Добавлено через 8 минут
Rudman132, вот с рекурсией и по проще.
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
#include <iostream>
 
size_t convert(int input, int* arr, size_t idx = 0u)
{
    if (input)
    {
        arr[idx] = input % 2u;
        return convert(input / 2u, arr, ++idx);
    }
    else
        return idx;
}
 
int main()
{
    size_t num;
    std::cin >> num;
    int* a = new int[500u];
    size_t count_digit = convert(num, a);
    for (int idx = count_digit - 1; idx >= 0; --idx)
    {
        std::cout << a[idx];
    }
    std::cout << "\n";
    delete[] a;
 
    return 0;
}
Добавлено через 1 минуту
Цитата Сообщение от SomniPhobia Посмотреть сообщение
if (input)
Означает
C++
1
if (input != 0u)
Добавлено через 3 минуты
Rudman132, чтобы был перевод в другую систему счисления в строках 7 и 8 вместо 2 укажи какую надо систему счисления. Лучше сделать отдельной переменной: Аргументом функции передавать основание системы счисления, в которую нужно конвертировать это число.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.08.2019, 17:01

Написать рекурсивную функцию перевода числа с десятичной системы исчисления в двоичную
Здравствуйте! Нужно написать рекурсивную функцию перевода числа с десятичной системы исчисления в...

Написать рекурсивную процедуру перевода натурального числа из десятичной системы счисления в двоичную
Здравствуйте. Помогите написать рекурсивную процедуру перевода натурального числа из десятичной...

Рекурсивная функция для перевода данного натурального числа в заданную систему счисления
Составить рекурсивную функцию для перевода данного натурального числа в р-ичную систему счисления...

Перевод из десятичной системы счисления в двоичную, восьмеричную, 16-ричную
создание программы для проверки перевода чисел из десятичной системы счисления в...


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

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

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