Несколько раз приносил лут из сна в реальность а оказывалось что проснулся в фейковой реальности.
минутка интересных фактов:
обоссанные штаны - единственный лут, который можно принести из сна в реальность.
Загадка: что делает этот код?
unsigned c=0; do something(c); while(c=c-m&m);
А этот?
unsigned c=0; while(c=c-m&m) something(c);
Встречали ли вы раньше этот трюк?
FordPerfect
> m
?
Aroch
Какое-то unsigned число заданное снаружи.
FordPerfect
итерируется от 0 до m по правилу с = (с - m)&m; Не понятно только зачем это может понадобиться, видимо в каком-то спец. случае.
Aroch
> итерируется
На всякий случай: эта итерация не обязательно проходит все числа в диапазоне [0;m].
FordPerfect
do while обязательно выполняется первый раз, а while - нет
FordPerfect
> На всякий случай: эта итерация не обязательно проходит все числа в диапазоне
> [0;m].
разумеется, закономерность какая-то есть, но мне не понятно в каких задачах она нужна. Поэтому колись, где это понадобилось?
FordPerfect
> while(c=c-m&m);
Как это читать-тааа?
c = (( c-m) & m)
?
Предлагаю желающим подумать самим, оно забавное.
Ответ:
Вычитал у https://twitter.com/rygorous , хз где он его нашёл.
1 frag / 2 deaths
> c = ((c-m) & m)
Да. Раз загадка - синтаксис тоже загадочный.
FordPerfect
> Код обходит все подмаски битовой маски m, в порядке возрастания.
ну такое себе... хоть работа с масками и требуется иногда, но чтобы обходить все подмаски. Слишком редкий кейс, но решение конечно красивое, особенно если захочешь потом позже вернуться и понять без комментариев, а что тут происходит то :)
Загуглил алгоритм в порядке убывания:
https://e-maxx.ru/algo/all_submasks
int s = m; while (s > 0) { ... можно использовать s ... s = ( s-1) & m; }
Пусть у нас есть текущая подмаска s, и мы хотим перейти к следующей подмаске. Отнимем от маски s единицу, тем самым мы снимем самый правый единичный бит, а все биты правее него поставятся в 1. Затем удалим все "лишние" единичные биты, которые не входят в маску m и потому не могут входить в подмаску. Удаление осуществляется битовой операцией &m. В результате мы "обрежем" маску s-1 до того наибольшего значения, которое она может принять, т.е. до следующей подмаски после s в порядке убывания.
entryway
я бы оформил для мат. либы в виде пары функций:
inline auto nextSubmask(uint32_t value, uint32_t mask) -> uint32_t { return ( value - mask) & mask; } inline auto prevSubmask( uint32_t value, uint32_t mask) -> uint32_t { return ( value - 1) & mask; } // example of usage while( value = nextSubmask( value, mask)) cout << value << " ";