Ну, что опять пятница и опять неудержимо хочется поговнокодить.
Вспомнился тут конкурс, который объявляли ребята из летней школы программирования на самый изращенческий (если желаете «по-умному», то «самый перверсивный») способ реверсирование байта. Т.е. задача реверсировать байт, чтобы 0-ой бит оказался на 7-ой позиции, 1-ый – на 6-ой и т.д. и сделать это надо было наиболее извращённым способом.
Ну, сказала Сова, обычная процедура в таких случаях нижеследующая самая что ни на есть обычная программа реверсирования байта (которую использует чуть менее, чем все) выглядит примерно так:
uint8_t bitReverseFast(uint8_t b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; // меняем местами нибблы (4-ки битов)
b = (b & 0xCC) >> 2 | (b & 0x33) << 2; // внутри каждой четвёрки меняем местами пары битов
return (b & 0xAA) >> 1 | (b & 0x55) << 1; // внутри каждой пары меняем местами биты
}
как видите, ничего особо умного и сложного нет и такими приземлённо-рутинными вещами армянское радио, разумеется, не занимается.
Задача стояла сделать тоже самое но … «через Альпы». Мы почему-то были уверены, что победит русский студент – у нас ведь всё «через Альпы» делается, так что нашим ребятам не привыкать. Но, к нашему удивлению, победил китайский участник (видимо, с «Альпами» у них в Поднебесной тоже всё в порядке).
Решение было вот таким:
uint8_t bitReversePervert(const uint8_t b) {
return (b * 0x0202020202ull & 0x010884422010ull) % 1023; // сами разбирайтесь :-)
}
Можете запустить и убедиться, что оба решения вполне исправно реверсируют биты.
Решение же китайца обладает особой ценностью ещё и потому, что оно не только выглядит зубодробительно, но и работает … я и подумать не мог, что эту операцию можно выполнять так долго. Оно медленнее стандартного решения, приведённого первым, в тридцать четыре раза!
Ну, вот такой вот говнокодик. Если вставить эту функцию в проект, да ещё и без комментариев (а лучше и название оставить типа f()
), то выглядеть она будет вполне достойно
Кто-то может предложить более гнусное извращение на эту тему?