Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
0 / 0 / 0
Регистрация: 10.10.2021
Сообщений: 15

Реализовать циклический сдвиг влево на указанное количество бит

05.12.2022, 22:09. Показов 1189. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброе время! У меня проблема. Мне необходимо реализовать циклический побитовый сдвиг влево, с маленькими числами все отлично работает, но когда ввожу максимальное число для 64 бит(9223372036854775807) то мне выдает другое число
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
#include <iostream>
#include <sstream>
using namespace std;
 
 
//Преобразуем число в массив символов, которые представляют число в двоичном виде
void NumToChars(long long num, char num2[], int arr_size) {
    long long one = 1;
    for (int i = arr_size - 1; i >= 0; i--) {
        if (num & (one << i)) {//сдвигаем биты
            num2[arr_size - 1 - i] = '1';
        }
        else {
            num2[arr_size - 1 - i] = '0';
        }
    }
}
//создаем строку из двоичного представления числа, добавляя пробелы для удобства
string CharsToString(char num2[], int arr_size) {
    string s = "";
    for (int i = 0; i < arr_size; i++) {
        s += num2[i];
        if ((i + 1) % 8 == 0)s += " ";
    }return s;
}
//Меням биты в двоичном представлении числа
long long ShiftBits(unsigned long long num, int shift) {
    unsigned long long res = (num << shift) | (num >> (64 - shift));
    return res;
}
//преобразуем двоичное представление в десятиричное число
long long CharsToLongLong(char arr[], int arr_size) {
    long long res = 0;
    int deg;
    for (int i = arr_size - 1; i >= 0; i--) {
        if (arr[i] == '1') {
            deg = arr_size - 1 - i;
            res += pow(2, deg);
        }
    }return res;
}
 
 
int main(int argc, char* argv[]) {
    setlocale(LC_ALL, "ru");
 
    //Если количество аргументов указано верно
    if (argc == 3) {
        unsigned long long num;
        int shift;
        bool correct[2] = { true,true };
        //Создаем из массива символов потоки строк
        stringstream convert[2];
        for (int i = 0; i < 2; i++) {
            convert[i].str(argv[i + 1]);
        }
        //Конвертируем значения
        //конвертируем исходное число
        if (!(convert[0] >> num)) // выполняем конвертацию
            correct[0] = false; // если конвертация терпит неудачу, то отмечаем это
 
        //конвертируем число для сдвига
        if (!(convert[1] >> shift)) // выполняем конвертацию
            correct[1] = false; // если конвертация терпит неудачу, то отмечаем это
 
        //Если конвертация прошла успешно
        if (correct[0] && correct[1]) {
 
            //Если позиция указана верно
            if (shift > 0) {
                //Перевод в двоичный вид
                char input[64];
                NumToChars(num, input, 64);
                cout << "Исходное число в десятиричном виде: " << endl << num << endl;
                cout << "Исходное число в двоичном виде: " << endl << CharsToString(input, 64) << endl;
                //сдвиг
                cout << "Сдвиг влево на число бит: " << shift << endl;
                char res[64];
                unsigned long long r = ShiftBits(num, shift);
                NumToChars(r, res, 64);
                cout << "Результат сдвига:" << endl << CharsToString(res, 64) << endl;
                //перевод из двоичного в лонг лонг
                unsigned long long new_num = CharsToLongLong(res, 64);
                cout << "Получившееся число: " << endl << new_num << endl;
            }
            else { cout << "Число сдвига должно быть больше 0" << endl; }
        }
        //Если конвертация прошла неуспешно
        else {
            cout << "Не получилось преобразовать следующие числа:" << endl;
            if (!correct[0]) { cout << "Исходное число - " << argv[1] << endl; }
            if (!correct[1]) { cout << "Число сдвига - " << argv[2] << endl; }
        }
    }
    //если количество аргументов было другое - говорим какие аргументы и в каком порядке должны быть
    else {
        cout << "Аргументы программы:" << endl;
        cout << "1) Исходное число" << endl;
        cout << "2) число, на которое нужно сдвинуть влево" << endl;
    }
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
05.12.2022, 22:09
Ответы с готовыми решениями:

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

Циклический сдвиг влево элементов массива на заданное количество позиций
Осуществить циклическое смещение компонентов вектора A(a1,a2,...,an) на l позиций влево таким образом, чтобы преобразованный вектор...

Циклический побитовый сдвиг числа вправо на указанное количество бит, но только для нечетных битов
Реализовать циклический побитный сдвиг числа вправо на указанное число(n), но только для нечетных битов Условия: Реализация задания в...

16
фрилансер
 Аватар для Алексей1153
6444 / 5637 / 1128
Регистрация: 11.10.2019
Сообщений: 14,994
05.12.2022, 22:32
Mentiorowski, чуток упростить можно

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <bitset>
#include <climits>
 
int main()
{
    uint64_t value=0b1100111000111100001111001100110011111111000000001111000010101010;
    size_t leftshift=3;
    
    constexpr size_t len=sizeof(value)*CHAR_BIT;
    
    uint64_t right_mask=std::numeric_limits<uint64_t>::max()>>leftshift;
    uint64_t left_mask=~right_mask;
    
    uint64_t result=((value&right_mask)<<leftshift) | ((value&left_mask)>>(len-leftshift));
    
    std::cout<<"value ="<<std::bitset<len>{value }<<'\n';
    std::cout<<"result="<<std::bitset<len>{result}<<'\n';
}
value =1100111000111100001111001100110011111111000000001111000010101010
result=0111000111100001111001100110011111111000000001111000010101010110
0
0 / 0 / 0
Регистрация: 10.10.2021
Сообщений: 15
05.12.2022, 22:37  [ТС]
Проблема именно в том, что когда я ввожу это максимальное число и сдвигаю на 64 бит(по кругу то есть) , он новое число переводит из двоичной в десятичной неправильно. Пример:
Input: 9223372036854775803(введеное число) 64(сдвиг влево на 64)
Output: Исходное число в двоичном виде:
01111111 11111111 11111111 11111111 11111111 11111111 11111111 11111011
Сдвиг влево на число бит: 64
Результат сдвига:
01111111 11111111 11111111 11111111 11111111 11111111 11111111 11111011
Получившееся число:
9223372036854775808
То есть не соответсвует введеному мною числу, хотя именно в двоичном коде сдвиг организован верно
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
05.12.2022, 22:43
Цитата Сообщение от Mentiorowski Посмотреть сообщение
он новое число переводит из двоичной в десятичной неправильно
Вот из-за этого гомнокода:
Цитата Сообщение от Mentiorowski Посмотреть сообщение
res += pow(2, deg);
0
0 / 0 / 0
Регистрация: 10.10.2021
Сообщений: 15
05.12.2022, 23:02  [ТС]
Но это же и есть перевод в десятиричное число, как где у меня единицы, там сумма двух степени, так же и переводит, не совсем понимаю
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
05.12.2022, 23:44
Цитата Сообщение от Mentiorowski Посмотреть сообщение
не совсем понимаю
Функция pow работает с типом double.
У double мантисса всего 52 бита.
Для получения натуральной степени двойки используй битовый сдвиг.
2n = (1ULL << n)

А вместо сложения - побитовое ИЛИ.
0
0 / 0 / 0
Регистрация: 10.10.2021
Сообщений: 15
06.12.2022, 00:02  [ТС]
Я воспользовался, стал получать совсем иные значения
C++
1
2
deg = (1ULL << i);
 res = res | deg;
Input: 9223372036854775903 64
Исходное число в десятиричном виде:
9223372036854775903
Исходное число в двоичном виде:
10000000 00000000 00000000 00000000 00000000 00000000 00000000 01011111
Сдвиг влево на число бит: 64
Результат сдвига:
10000000 00000000 00000000 00000000 00000000 00000000 00000000 01011111
Получившееся число:
1
То есть проблема также с переводом. Я как-то неправильно реализовал?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
06.12.2022, 00:18
Цитата Сообщение от Mentiorowski Посмотреть сообщение
deg = (1ULL << i);
А deg у тебя какого типа?
0
0 / 0 / 0
Регистрация: 10.10.2021
Сообщений: 15
06.12.2022, 00:19  [ТС]
integer
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
06.12.2022, 00:20
Цитата Сообщение от Mentiorowski Посмотреть сообщение
integer
Что это? Нет такого типа в С++.
0
0 / 0 / 0
Регистрация: 10.10.2021
Сообщений: 15
06.12.2022, 00:20  [ТС]
Целое число, int
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
06.12.2022, 00:22
Цитата Сообщение от Mentiorowski Посмотреть сообщение
int
Ну и как думаешь, поместится, например, 240 в int?
0
0 / 0 / 0
Регистрация: 10.10.2021
Сообщений: 15
06.12.2022, 00:25  [ТС]
А, то есть меня интересует long long? Но переменная deg же вмещает в себя значение степени, а не само число возведенную в неё
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
06.12.2022, 00:29
Цитата Сообщение от Mentiorowski Посмотреть сообщение
Но переменная deg же вмещает в себя значение степени, а не само число возведенную в неё
Я не знаю, что она там по твоей задумке вмещает, но справа от оператора присваивания находится именно чило 2 возведенное в степень i и имеет тип unsigned long long.
0
0 / 0 / 0
Регистрация: 10.10.2021
Сообщений: 15
06.12.2022, 00:37  [ТС]
Такая проблема возникла: я изменил тип переменной deg на long long, я все равно получаю вывод совсем рандомного содержания в десятиричном виде
C++
1
2
3
4
5
6
7
8
9
10
long long CharsToLongLong(char arr[], int arr_size) {
    long long res = 0;
   unsigned long long deg;
    for (int i = arr_size - 1; i >= 0; i--) {
        if (arr[i] == '1') {
            deg = (1ULL << i);
            res = res | deg;
            
        }
    }return res;
Я всё таки что-то упускаю?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
06.12.2022, 00:41
Лучший ответ Сообщение было отмечено Mentiorowski как решение

Решение

Mentiorowski, ну наверное потому, что у тебя i отображает не степень. Почему в оригинале у тебя зависимость степени от i была такой:
Цитата Сообщение от Mentiorowski Посмотреть сообщение
arr_size - 1 - i
А тут вдруг стала просто i?
1
0 / 0 / 0
Регистрация: 10.10.2021
Сообщений: 15
06.12.2022, 00:47  [ТС]
Благодарю за помощь!) Совсем забыл про arr_size
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.12.2022, 00:47
Помогаю со студенческими работами здесь

Циклический сдвиг на 11 бит влево
Здравствуйте форумчане, ломаю голову, как можно выполнить сдвиг на 11 бит влево вот этого двоичного кода: 00011100010010000111000101111101 ...

Циклический сдвиг списка вправо или влево на указанное число позиций
def func(l, n): return l + l try: s=input('Введите список чисел через пробел: ') l = list(map(int, s.split())) if...

Циклический сдвиг в целом числе на n бит влево и вправо
Написать функцию циклического сдвига в 2𝑝 разрядном целом числе на 𝑛 бит влево и вправо.

Реализовать программу, которая будет выполнять циклический сдвиг списка влево
Необходимо реализовать программу, которая будет выполнять циклический сдвиг списка влево. Как это сделать? Помогите Вот код ввода...

Циклический сдвиг элементов массива влево на заданное количество позиций
Составить процедуру (или функцию), которая переставляет первые k элементов массива A в конец (число k задается пользователем): A, A, …,...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru