Форум программистов, компьютерный форум CyberForum.ru

Циклический сдвиг, где подвох? - C++

Восстановить пароль Регистрация
 
T-L-oleg
0 / 0 / 0
Регистрация: 26.01.2013
Сообщений: 5
26.01.2013, 01:36     Циклический сдвиг, где подвох? #1
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
/*
Проект 7-1
Функции циклического сдвига байта влево и вправо.
*/
 
#include<iostream>
 
using namespace std;
 
char lrotate(unsigned int val, int n);
char rrotate(unsigned int val, int n);
void show_binary(unsigned int u);
 
int main()
{
    setlocale(LC_CTYPE, "russian");
 
    char ch = 'T';
 
    cout << "Исходное значение в двоичном коде:\n";
    show_binary(ch);
 
    cout << "Циклический сдвиг вправо 8 раз:\n";
    for(int i = 0; i < 8; i++)
    {
        ch = rrotate(ch, 1);
        show_binary(ch);
    }
 
    cout << "Циклический сдвиг влево 8 раз:\n";
    for(int i = 0; i < 8; i++)
    {
        ch = lrotate(ch, 1);
        show_binary(ch);
    }
 
    return 0;
}
 
char lrotate(unsigned int val, int n)
{
    unsigned int t;
 
    t = val;
 
    for(int i = 0; i < n; i++)
    {
        t = t << 1;
 
        if(t & 256)
            t = t | 1;
    }
 
    return t;
}
 
char rrotate(unsigned int val, int n)
{
    unsigned int t;
 
    t = val;
 
    t = t << 8;
 
    for(int i = 0; i < n; i++)
    {
        t = t >> 1;
 
        if(t & 128)
        {
            t = t | 32768;
        }
    }
 
    t = t >> 8;
 
    return t;
}
 
void show_binary(unsigned int u)
{
    int t;
 
    for(t = 128; t > 0; t = t / 2)
        if(u & t) cout << "1 ";
        else cout << "0 ";
 
        cout << "\n";
}
Беда в том что результат такой:

Исходное значение в двоичном коде:
0 1 0 1 0 1 0 0
Циклический сдвиг вправо 8 раз:
0 0 1 0 1 0 1 0
0 0 0 1 0 1 0 1
1 0 0 0 1 0 1 0
1 1 0 0 0 1 0 1
1 1 1 0 0 0 1 0
1 1 1 1 0 0 0 1
1 1 1 1 1 0 0 0
1 1 1 1 1 1 0 0
Циклический сдвиг влево 8 раз:
1 1 1 1 1 0 0 1
1 1 1 1 0 0 1 1
1 1 1 0 0 1 1 1
1 1 0 0 1 1 1 1
1 0 0 1 1 1 1 1
0 0 1 1 1 1 1 1
0 1 1 1 1 1 1 0
1 1 1 1 1 1 0 0
Для продолжения нажмите любую клавишу . . .

В чем загвостка? Беда только в rrotate().
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
26.01.2013, 01:44     Циклический сдвиг, где подвох? #2
Цитата Сообщение от T-L-oleg Посмотреть сообщение
t = t << 1;
if(t & 256)
* * * * * * t = t | 1;
C++
1
2
3
4
5
 
        if(t & 128)
            t =( t << 1)| 1;
        else
            t = t << 1;
Добавлено через 1 минуту
Цитата Сообщение от T-L-oleg Посмотреть сообщение
(t & 256)
всегда 0
256 это 1 0000 0000
t это же xxxx xxxx
их побитовое И это 0
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
26.01.2013, 01:48     Циклический сдвиг, где подвох? #3
C++
1
char ch = 'T';
может unsigned сделать?
C++
1
unsigned char ch = 'T';
Циклический сдвиг, где подвох?
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
26.01.2013, 01:49     Циклический сдвиг, где подвох? #4
Цитата Сообщение от T-L-oleg Посмотреть сообщение
t = t >> 1;
if(t & 128)
* * * * {
* * * * * * t = t | 32768;
* * * * }
аналогично
C++
1
2
if(t & 1)* t = (t>>1)|128;
else t=(t>>1)&0x7F;
vua72
410 / 410 / 83
Регистрация: 28.11.2010
Сообщений: 1,158
26.01.2013, 12:58     Циклический сдвиг, где подвох? #5
я бы так делал и не мешал рамерности и типы данных
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
/*
Проект 7-1
Функции циклического сдвига байта влево и вправо.
*/
#include<iostream>
using namespace std;
 
unsigned char lrotate(unsigned char val, unsigned char n);
unsigned char rrotate(unsigned char val, unsigned char n);
void show_binary(unsigned char u);
 
int main()
{
    setlocale(LC_CTYPE, "russian");
    unsigned char ch = 0x07;
    cout << "Исходное значение в двоичном коде:\n";
    show_binary(ch);
    cout << "Циклический сдвиг вправо 8 раз:\n";
    for(int i = 0; i < 8; i++) {
        ch = rrotate(ch, 1);
        show_binary(ch);
    }
    cout << "Циклический сдвиг влево 8 раз:\n";
    for(int i = 0; i < 8; i++) {
        ch = lrotate(ch, 1);
        show_binary(ch);
    }
    return 0;
}
unsigned char lrotate(unsigned char val, unsigned char n)
{
    unsigned char t=val;
    for(unsigned char i = 1; i <= n; ++i) {
        t & 0x80 ? (t<<=1)|=0x01 : (t<<=1)|=0x00;
        }
    
    return t;
}
unsigned char rrotate(unsigned char val, unsigned char n)
{
    unsigned char t=val;
    for(unsigned char i = 1; i <= n; ++i) {
        t & 0x01 ? (t>>=1)|= 0x80 : (t>>=1) &= 0x7f ;
    }
    return t;
}
void show_binary(unsigned char u)
{
    unsigned char t;
    for(t = 0x80; t > 0; t >>= 1)
        if(u & t) cout << "1 ";
        else cout << "0 ";
    cout << "\n";
}
Добавлено через 1 минуту
не нравятся тернарные операторы - замените на if();
T-L-oleg
0 / 0 / 0
Регистрация: 26.01.2013
Сообщений: 5
26.01.2013, 13:23  [ТС]     Циклический сдвиг, где подвох? #6
Все спс, char было объявленно со знаком, отсюда и проблема.
vua72
410 / 410 / 83
Регистрация: 28.11.2010
Сообщений: 1,158
26.01.2013, 17:30     Циклический сдвиг, где подвох? #7
Цитата Сообщение от T-L-oleg Посмотреть сообщение
Все спс, char было объявленно со знаком, отсюда и проблема.
Извините, но проблема у вас не в знаковом типе данных, а в тех вывертах - наворотах, которые вы написали.
Особенно поражает, что вы перегоняете туда-сюда 1 - байтное и 4-байтное числа, при этом появляются экзотические сравнения типа
C++
1
if(t & 256)
и операции
C++
1
t = t | 32768;
, которых для однобайтных чисел не может быть в принципе. Извините, но на месте вашего преподавателя, я б не защитал ваш вариант решения как правильный.
Такая программа показывает полное отсутствие понимания предмета.
T-L-oleg
0 / 0 / 0
Регистрация: 26.01.2013
Сообщений: 5
26.01.2013, 18:05  [ТС]     Циклический сдвиг, где подвох? #8
Спосибо за замечание, извиняюсь за столь "неприемлемый стиль" (все притензии к Герберту Шилдту, автору столь замечательной книги), в любом случае мои "выверты - навороты" являются вполне уместными, а преобразования типов, проблем невызвало вообще, ну и "полным отсутствием понимания предмета" я бы на вашем месте это называть нестал. Извиняюсь за оффтоп.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.01.2013, 19:07     Циклический сдвиг, где подвох?
Еще ссылки по теме:

Циклический сдвиг C++
C++ Циклический сдвиг
Дан массив размера N. Осуществить циклический сдвиг элементов массива вправо на k позиций, где k – индекс максимального элемента C++

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

Или воспользуйтесь поиском по форуму:
vua72
26.01.2013, 19:07     Циклический сдвиг, где подвох?
  #9

Не по теме:

Шилдт не панацея и не последняя инстанция. Циклический сдвиг - это сдвиг через нулевой разряд (вправо) или n-1 разряд (влево), есть сдвиги через флаг переноса, но нет свига через другое число, которое при этом в 4 раза больше операнда, который двигают. А теперь поробуйте адекватно описать ваш или Шилдта алгоритм сдвига. Давайте попробуем. Берем число, делаем его в 4 раза больше и сдвигаем его на 8 разрядов влево. Теперь двигаем вправо и начинаем крутить число. А на месте это делать религия Шилдту не позволяет? И в конце начинаем задвигать число назад. И да, а вдруг мы забыли про знаковый разряд, то вообще после первого сдвига наше решение окажется неправильным, вот незадача, оказывается мы уже не свое число крутим а содержимое знакового разрядв. Так в чем тут есть понимание работы сдвига? Просто неочевидный алгоритм, который к тому же требует и дополнительных накладных расходов памяти.
Поэтому я и сказал о непонимании предмета, мало того, тут еще надо и число n нужно преобразовывать, чтоб по кругу не крутить лишний раз, так как это реализовано, например, в интеловских процессорах.
Ну если итак сойдет, то пусть работает, извините, что вас с Шилдтом обвинил в плохом стиле, больше не буду.

Yandex
Объявления
26.01.2013, 19:07     Циклический сдвиг, где подвох?
Ответ Создать тему
Опции темы

Текущее время: 23:41. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru