Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
108 / 108 / 23
Регистрация: 21.03.2010
Сообщений: 445

Реализация оператора декремента

10.10.2013, 00:01. Показов 835. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
На лабах задали написать алгоритм "обращенного двоичного счета", который, на сколько я понял (не удалось уточнить гуглением), представляет из себя перебор бинарный векторов в порядке лексикографического убывания. Т. е. в с++ осуществляется операцией --. Естественно, использовать -- намного проще и быстрее. Но тогда что останется от лабы?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
void print_v(unsigned char v) {
    for (int i(8); i--; std::cout << static_cast<bool>(v & 1 << i)) {}
    std::cout << std::endl;
}
inline unsigned char& decr(register unsigned char& v) {
    if (!v) return v = -1;//чтобы не писать лишний проверок в цикле
    register unsigned char i(1);
    while (!(v & i))  i <<= 1;//Ищем первый ненулевой элемент
    v &= ~i;//Зануляем его
    while (i >>= 1) v |= i;//проставляем в младшие разряды единицы
    return v;
}
int main() {
    unsigned char b(0);
    while (decr(b))//Эквивалентно выражению while (--b)
        print_v(b);//Вывести бинарный вектор
    return 0;
}
Короче, написан вариант функции со следующими требованиями к коду:
1. Это всё-таки должен быть с++ а не какой-нибудь там ассемблер
2. Написать максимально производительный код.
Опубликовано здесь по двум причинам
1. Я доволен результатом и хочу продемонстрировать его окружающим
2. Я уверен, что найдутся люди, которые дадут дельные советы по совершенствованию написанного.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.10.2013, 00:01
Ответы с готовыми решениями:

Перегрузка оператора декремента
Приветствую Вас форумчане:dance3: Столкнулся с такой проблемой при перегрузке операции декремента для своего класса, вот код: ...

Перегрузка оператора декремента
Собственно, нужно написать программу для уменьшения значения переменной на 10, путем перегрузки оператора декремента(&quot;--&quot;). Не...

Перегрузка оператора инкремента/декремента через friend
Нужно реализовать перегрузку унарного оператора через friend. Что я пытаюсь сделать: friend void operator -- ();//prototype void...

6
188 / 187 / 46
Регистрация: 24.03.2011
Сообщений: 670
10.10.2013, 00:17
А чем, собственно, обусловлена такая конструкция?)
C++
1
for (int i(8); i--; std::cout << static_cast<bool>(v & 1 << i)) {}
Особой красоты коду она не придает, даже наоборот. Ну и, по моему, стоит постфиксный декримент здесь заменить на префиксный (на int, конечно, выигрыша в скорости не заметишь=), но все таки). Но это так, сугубо мое мнение.)
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
10.10.2013, 00:20
Цитата Сообщение от CEBEP Посмотреть сообщение
register
этот register в коде на с++ до одного места, хочешь чтоб было на регистрах - используй ассемблер
0
108 / 108 / 23
Регистрация: 21.03.2010
Сообщений: 445
10.10.2013, 00:24  [ТС]
Цитата Сообщение от monolit Посмотреть сообщение
Особой красоты коду она не придает, даже наоборот.
Бесспорно. Да и вообще эта функция написана на скорую руку и без особого интереса... а с префиксным декрементом результат работы функции будет другой. Но вернёмся к --, на мой взгляд, вывод вектора тут совершенно не интересен.

Добавлено через 3 минуты
Цитата Сообщение от Jupiter Посмотреть сообщение
хочешь чтоб было на регистрах - используй ассемблер
Ну асемблеровский код использовать у меня возможности нет по причине очень поверхностного его знания. А стандарт описывает это словечко как вполне подходящее для такого случая так что почему бы и нет?

Меня больше интересует мнение профессионалав по таким вопросам как проверка например while (!(v & i)) этого условия... что тут в действительности происходит? можно ли использовать что-то более производительное чем неявное приведение типа (v & i) не равны константе 0 всегда, так что приведение типа тут по всей видимости есть.
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
10.10.2013, 00:41
Цитата Сообщение от CEBEP Посмотреть сообщение
А стандарт
A register specifier is a hint to the implementation that the variable so declared will be heavily used.
[ Note: the hint can be ignored and in most implementations it will be ignored if the address of the variable
is taken. This use is deprecated (see D.4). — end note
...
1
108 / 108 / 23
Регистрация: 21.03.2010
Сообщений: 445
10.10.2013, 01:33  [ТС]
спасибо, уберу.

Assembler
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
    unsigned char b(0);
00A81277  xor         bl,bl  
00A81279  lea         esp,[esp]  
    while (decr(b))//Эквивалентно выражению while (--b)
00A81280  test        bl,bl  
00A81282  jne         main+19h (0A81289h)  
00A81284  or          bl,0FFh  
00A81287  jmp         main+3Ah (0A812AAh)  
00A81289  mov         al,1  
00A8128B  test        al,bl  
00A8128D  jne         main+26h (0A81296h)  
00A8128F  nop  
00A81290  add         al,al  
00A81292  test        bl,al  
00A81294  je          main+20h (0A81290h)  
00A81296  mov         cl,al  
00A81298  not         cl  
00A8129A  and         bl,cl  
00A8129C  shr         al,1  
00A8129E  je          main+36h (0A812A6h)  
00A812A0  or          bl,al  
00A812A2  shr         al,1  
    while (decr(b))//Эквивалентно выражению while (--b)
00A812A4  jne         main+30h (0A812A0h)  
00A812A6  test        bl,bl  
00A812A8  je          main+81h (0A812F1h)  
00A812AA  movzx       eax,bl  
        print_v(b);//Вывести бинарный вектор
00A812AD  mov         edi,8  
00A812B2  mov         esi,100h  
00A812B7  mov         dword ptr [ebp-4],eax  
00A812BA  lea         ebx,[ebx]  
00A812C0  ror         esi,1  
00A812C2  mov         ecx,dword ptr ds:[0A8303Ch]  
00A812C8  test        esi,eax  
00A812CA  setne       al  
00A812CD  movzx       eax,al  
00A812D0  push        eax  
00A812D1  call        dword ptr ds:[0A8302Ch]  
00A812D7  mov         eax,dword ptr [ebp-4]  
00A812DA  dec         edi  
00A812DB  jne         main+50h (0A812C0h)  
00A812DD  push        dword ptr ds:[0A83024h]  
00A812E3  mov         ecx,dword ptr ds:[0A8303Ch]  
00A812E9  call        dword ptr ds:[0A83028h]  
00A812EF  jmp         main+10h (0A81280h)  
00A812F1  pop         edi  
00A812F2  pop         esi  
    return 0;
Вот что вывалилось при компиляции /O2. Видимо, он действительно вставился как инлайн. Но это единственный вывод, который я могу уверенно сделать по данному коду. Не могли бы вы её прокомментировать?

Добавлено через 8 минут
К стаи, на сколько я понял, переменные действительно возникают только в регистрах!

Добавлено через 4 минуты
*его - код а не вывод))

Добавлено через 5 минут
что-то меня поплавило к часу ночи. Короче, разобраться помогите)))

Добавлено через 24 минуты
Assembler
1
2
3
4
    while (--b)
010512BC  mov         al,byte ptr [ebp-1]  
010512BF  dec         al  
010512C1  dec         ebx
А как бы всё могло быть просто...
0
108 / 108 / 23
Регистрация: 21.03.2010
Сообщений: 445
12.10.2013, 18:53  [ТС]
короче печаль. ковырялся с этой ерундой полдня, даже 50 рублей отдал чтобы отчет на цветном принтере распечатать. Преподу вообще плевать - посмотрел, зачел... отчет не открывал даже...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
12.10.2013, 18:53
Помогаю со студенческими работами здесь

Вывести числа от 10 до нуля при помощи оператора декремента и цикла while
Здравствуйте. Как вывести каждое число в цикле while? Ведь он заканчивается на нуле и выводит ноль. Где нужно вставить вывод каждого...

Написать программу, которая демонстрирует разницу между операциями пре-декремента и пост-декремента
Написать программу, которая демонстрирует разницу между операциями переддекремента и постдекремента. Занести ее в тетрадь с пояснениями.

Реализация оператора [] для самописного класса String
Доброго времени суток. Пытаюсь написать самописный класс String. Вот что уже готово: struct String { String(const char *str...

Реализация перегрузки оператора (например, +, через др.перегруку, +)
Всем хай! Сходу к делу! У меня вопрос больше по технике кодирования. Есть юзер-класс &quot;Строка&quot; (фрагмент): class...

Одновременная реализация константного и неконстантного оператора [] в классе string
Вобщем, проблема в следующем: нужно реализовать обращение по индексу в классе string двумя вариантами оператора : константный (для чтения)...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru