В C/С++ какой самый простой способ изменить порядок бит в байте?

Вопрос:Хотя существует несколько способов обратного порядка бит в байте, мне любопытно, что такое "самый простой" для разработчика. И, обращаясь, я имею в виду: 1110 -> 0111 0010 -> 0100 Это похоже на, но не дубликат этого вопроса PHP. Это похоже на, но не дубликат this C вопроса. Этот вопрос требует самого простого метода для реализации

Вопрос:

Хотя существует несколько способов обратного порядка бит в байте, мне любопытно, что такое “самый простой” для разработчика. И, обращаясь, я имею в виду:

1110 -> 0111 0010 -> 0100

Это похоже на, но не дубликат этого вопроса PHP.

Это похоже на, но не дубликат this C вопроса. Этот вопрос требует самого простого метода для реализации разработчиком. “Лучший алгоритм” посвящен производительности памяти и процессора.

Лучший ответ:

Если вы говорите об одном байте, поиск по таблице, вероятно, лучший выбор, если по какой-то причине у вас нет доступных 256 байтов.

Ответ №1

Это должно работать:

unsigned char reverse(unsigned char b) { b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; b = (b & 0xCC) >> 2 | (b & 0x33) << 2; b = (b & 0xAA) >> 1 | (b & 0x55) << 1; return b; }

Сначала левые четыре бита заменяются правыми четырьмя битами. Затем все соседние пары меняются местами, а затем все соседние отдельные биты. Это приводит к обратному порядку.

Ответ №2

Я думаю, что таблица поиска должна быть одним из простейших методов. Однако вам не нужна полная таблица поиска.

//Index 1==0b0001 => 0b1000 //Index 7==0b0111 => 0b1110 //etc static unsigned char lookup[16] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf, }; uint8_t reverse(uint8_t n) { // Reverse the top and bottom nibble then swap them. return (lookup[n&0b1111] << 4) | lookup[n>>4]; } // Detailed breakdown of the math // + lookup reverse of bottom nibble // | + grab bottom nibble // | | + move bottom result into top nibble // | | | + combine the bottom and top results // | | | | + lookup reverse of top nibble // | | | | | + grab top nibble // V V V V V V // (lookup[n&0b1111] << 4) | lookup[n>>4]

Это довольно простое кодирование и проверка визуально.
В конечном итоге это может быть даже быстрее, чем полная таблица. Битовый ариф дешев, и таблица легко вписывается в строку кэша.

Ответ №3

Для решения многих проблем см. бит-скрипичные хаки. Очевидно, что отпадает необходимость в их копировании. =)

Например (на 32-разрядном ЦП):

uint8_t b = byte_to_reverse; b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;

Если “просто реализовать” означает что-то, что можно сделать без ссылки на экзамене или собеседовании, то самым безопасным вариантом является, вероятно, неэффективное копирование бит по одному в другую переменную в обратном порядке (уже показано в других ответах).

Ответ №4

Поскольку никто не опубликовал полное решение для поиска таблицы, вот мой:

unsigned char reverse_byte(unsigned char x) { static const unsigned char table[] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, }; return table[x]; } Ответ №5template <typename T> T reverse(T n, size_t b = sizeof(T) * CHAR_BIT) { assert(b <= std::numeric_limits<T>::digits); T rv = 0; for (size_t i = 0; i < b; ++i, n >>= 1) { rv = (rv << 1) | (n & 0x01); } return rv; }

EDIT:

Преобразовал его в шаблон с дополнительным битом

Ответ №6

Две строки:

for(i=0;i<8;i++) reversed |= ((original>>i) & 0b1)<<(7-i);

или если у вас есть проблемы с частью “0b1”:

for(i=0;i<8;i++) reversed |= ((original>>i) & 1)<<(7-i);

“original” – это байт, который вы хотите изменить.
“reverse” – результат, инициализированный 0.

Ответ №7

Хотя, вероятно, не переносимый, я бы использовал язык ассемблера.
Многие языки ассемблера имеют инструкции повернуть бит в флаг переноса и повернуть флаг переноса в слово (или байт).

Алгоритм:

for each bit in the data type: rotate bit into carry flag rotate carry flag into destination. end-for

Код языка высокого уровня для этого намного сложнее, потому что C и С++ не поддерживают вращение для переноса и поворота от переноса. Флаг переноса должен быть смоделирован.

Изменить: Язык ассемблера

; Enter with value to reverse in R0. ; Assume 8 bits per byte and byte is the native processor type. LODI, R2 8 ; Set up the bit counter Loop: RRC, R0 ; Rotate R0 right into the carry bit. RLC, R1 ; Rotate R1 left, then append carry bit. DJNZ, R2 Loop ; Decrement R2 and jump if non-zero to «loop» LODR, R0 R1 ; Move result into R0. Ответ №8

Я считаю, что следующее решение проще, чем другие алгоритмы с битами, которые я видел здесь.

unsigned char reverse_byte(char a) { return ((a & 0x1) << 7) | ((a & 0x2) << 5) | ((a & 0x4) << 3) | ((a & 0x8) << 1) | ((a & 0x10) >> 1) | ((a & 0x20) >> 3) | ((a & 0x40) >> 5) | ((a & 0x80) >> 7); }

Он получает каждый бит в байте и соответственно смещает его, начиная с первого до последнего.

Объяснение:

((a & 0x1) << 7) //get first bit on the right and shift it into the first left position | ((a & 0x2) << 5) //add it to the second bit and shift it into the second left position //and so on Ответ №9

Самый простой способ – это, вероятно, перебрать позиции битов в цикле:

unsigned char reverse(unsigned char c) { int shift; unsigned char result = 0; for (shift = 0; shift < CHAR_BIT; shift++) { if (c & (0x01 << shift)) result |= (0x80 >> shift); } return result; } Ответ №10

Возможно, вас заинтересует std::vector<bool> (то есть бит-упаковка) и std::bitset

Он должен быть самым простым в соответствии с запросом.

#include <iostream> #include <bitset> using namespace std; int main() { bitset<8> bs = 5; bitset<8> rev; for(int ii=0; ii!= bs.size(); ++ii) rev[bs.size()-ii-1] = bs[ii]; cerr << bs << » » << rev << endl; }

Другие варианты могут быть быстрее.

РЕДАКТИРОВАТЬ: я должен вам решить, используя std::vector<bool>

#include <algorithm> #include <iterator> #include <iostream> #include <vector> using namespace std; int main() { vector<bool> b{0,0,0,0,0,1,0,1}; reverse(b.begin(), b.end()); copy(b.begin(), b.end(), ostream_iterator<int>(cerr)); cerr << endl; }

Во втором примере требуется расширение С++ 0x (для инициализации массива с помощью {…}). Преимущество использования bitset или std::vector<bool> (или a boost::dynamic_bitset) заключается в том, что вы не ограничены байтами или словами, но можете отменить произвольное количество бит.

НТН

Ответ №11

Для очень ограниченного случая постоянного 8-битного ввода этот метод не требует памяти или ЦП во время выполнения:

#define MSB2LSB(b) (((b)&1?128:0)|((b)&2?64:0)|((b)&4?32:0)|((b)&8?16:0)|((b)&16?8:0)|((b)&32?4:0)|((b)&64?2:0)|((b)&128?1:0))

Я использовал это для ARINC-429, где порядок битов (порядковый номер) метки противоположен остальной части слова. Метка часто является константой и обычно восьмеричной.

Вот как я использовал ее для определения константы, потому что спецификация определяет эту метку как восьмеричное число с прямым порядком байтов 205.

#define LABEL_HF_COMM MSB2LSB(0205)

Еще примеры:

assert(0b00000000 == MSB2LSB(0b00000000)); assert(0b10000000 == MSB2LSB(0b00000001)); assert(0b11000000 == MSB2LSB(0b00000011)); assert(0b11100000 == MSB2LSB(0b00000111)); assert(0b11110000 == MSB2LSB(0b00001111)); assert(0b11111000 == MSB2LSB(0b00011111)); assert(0b11111100 == MSB2LSB(0b00111111)); assert(0b11111110 == MSB2LSB(0b01111111)); assert(0b11111111 == MSB2LSB(0b11111111)); assert(0b10101010 == MSB2LSB(0b01010101)); Ответ №12

Поиск в таблице или

uint8_t rev_byte(uint8_t x) { uint8_t y; uint8_t m = 1; while (m) { y >>= 1; if (m&x) { y |= 0x80; } m <<=1; } return y; }

изменить

Посмотрите здесь для других решений, которые могут работать лучше для вас

Ответ №13

Перед внедрением любого алгоритмического решения проверьте язык ассемблера для любой архитектуры процессора, которую вы используете. Ваша архитектура может включать в себя инструкции, которые обрабатывают побитовые манипуляции, подобные этому (и что может быть проще, чем одна инструкция по сборке?).

Если такая инструкция недоступна, я бы предложил перейти с маршрутом таблицы поиска. Вы можете написать script/program для генерации таблицы для вас, а операции поиска будут быстрее, чем любой из алгоритмов обратного преобразования бит (за счет необходимости хранить таблицу поиска где-нибудь).

Ответ №14

более медленная, но более простая реализация:

static int swap_bit(unsigned char unit) { /* * swap bit[7] and bit[0] */ unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01)) << 7) | (unit & 0x7f)); unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01))) | (unit & 0xfe)); unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01)) << 7) | (unit & 0x7f)); /* * swap bit[6] and bit[1] */ unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02)) << 5) | (unit & 0xbf)); unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02))) | (unit & 0xfd)); unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02)) << 5) | (unit & 0xbf)); /* * swap bit[5] and bit[2] */ unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04)) << 3) | (unit & 0xdf)); unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04))) | (unit & 0xfb)); unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04)) << 3) | (unit & 0xdf)); /* * swap bit[4] and bit[3] */ unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08)) << 1) | (unit & 0xef)); unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08))) | (unit & 0xf7)); unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08)) << 1) | (unit & 0xef)); return unit; } Ответ №15

Может ли это быть быстрым решением?

int byte_to_be_reversed = ((byte_to_be_reversed>>7)&0x01)|((byte_to_be_reversed>>5)&0x02)| ((byte_to_be_reversed>>3)&0x04)|((byte_to_be_reversed>>1)&0x08)| ((byte_to_be_reversed<<7)&0x80)|((byte_to_be_reversed<<5)&0x40)| ((byte_to_be_reversed<<3)&0x20)|((byte_to_be_reversed<<1)&0x10);

Получает избавление от суеты использования цикла for! но эксперты, пожалуйста, скажите мне, если это эффективно и быстрее?

Ответ №16

Эта простая функция использует маску для проверки каждого бита входного байта и передачи его в сдвиговый выход:

char Reverse_Bits(char input) { char output = 0; for (unsigned char mask = 1; mask > 0; mask <<= 1) { output <<= 1; if (input & mask) output |= 1; } return output; } Ответ №17

Этот вариант основан на BobStein-VisiBone при условии

#define reverse_1byte(b) ( ((uint8_t)b & 0b00000001) ? 0b10000000 : 0 ) | ( ((uint8_t)b & 0b00000010) ? 0b01000000 : 0 ) | ( ((uint8_t)b & 0b00000100) ? 0b00100000 : 0 ) | ( ((uint8_t)b & 0b00001000) ? 0b00010000 : 0 ) | ( ((uint8_t)b & 0b00010000) ? 0b00001000 : 0 ) | ( ((uint8_t)b & 0b00100000) ? 0b00000100 : 0 ) | ( ((uint8_t)b & 0b01000000) ? 0b00000010 : 0 ) | ( ((uint8_t)b & 0b10000000) ? 0b00000001 : 0 )

Мне это очень нравится, потому что компилятор автоматически обрабатывает эту работу для вас, поэтому для этого не требуются дополнительные ресурсы.

это также можно расширить до 16-битов…

#define reverse_2byte(b) ( ((uint16_t)b & 0b0000000000000001) ? 0b1000000000000000 : 0 ) | ( ((uint16_t)b & 0b0000000000000010) ? 0b0100000000000000 : 0 ) | ( ((uint16_t)b & 0b0000000000000100) ? 0b0010000000000000 : 0 ) | ( ((uint16_t)b & 0b0000000000001000) ? 0b0001000000000000 : 0 ) | ( ((uint16_t)b & 0b0000000000010000) ? 0b0000100000000000 : 0 ) | ( ((uint16_t)b & 0b0000000000100000) ? 0b0000010000000000 : 0 ) | ( ((uint16_t)b & 0b0000000001000000) ? 0b0000001000000000 : 0 ) | ( ((uint16_t)b & 0b0000000010000000) ? 0b0000000100000000 : 0 ) | ( ((uint16_t)b & 0b0000000100000000) ? 0b0000000010000000 : 0 ) | ( ((uint16_t)b & 0b0000001000000000) ? 0b0000000001000000 : 0 ) | ( ((uint16_t)b & 0b0000010000000000) ? 0b0000000000100000 : 0 ) | ( ((uint16_t)b & 0b0000100000000000) ? 0b0000000000010000 : 0 ) | ( ((uint16_t)b & 0b0001000000000000) ? 0b0000000000001000 : 0 ) | ( ((uint16_t)b & 0b0010000000000000) ? 0b0000000000000100 : 0 ) | ( ((uint16_t)b & 0b0100000000000000) ? 0b0000000000000010 : 0 ) | ( ((uint16_t)b & 0b1000000000000000) ? 0b0000000000000001 : 0 ) Ответ №18#include <stdio.h> #include <stdlib.h> int main() { int i; unsigned char rev = 0x70 ; // 0b01110000 unsigned char tmp = 0; for(i=0;i<8;i++) { tmp |= ( ((rev & (1<<i))?1:0) << (7-i)); } rev = tmp; printf(«%x», rev); //0b00001110 binary value of given number return 0; } Ответ №19typedef struct { uint8_t b0:1; uint8_t b1:1; uint8_t b2:1; uint8_t b3:1; uint8_t b4:1; uint8_t b5:1; uint8_t b6:1; uint8_t b7:1; } bits_t; uint8_t reverse_bits(uint8_t src) { uint8_t dst = 0x0; bits_t *src_bits = (bits_t *)&src; bits_t *dst_bits = (bits_t *)&dst; dst_bits->b0 = src_bits->b7; dst_bits->b1 = src_bits->b6; dst_bits->b2 = src_bits->b5; dst_bits->b3 = src_bits->b4; dst_bits->b4 = src_bits->b3; dst_bits->b5 = src_bits->b2; dst_bits->b6 = src_bits->b1; dst_bits->b7 = src_bits->b0; return dst; } Ответ №20

Я думаю, что это достаточно просто

uint8_t reverse(uint8_t a) { unsigned w = ((a << 7) & 0x0880) | ((a << 5) & 0x0440) | ((a << 3) & 0x0220) | ((a << 1) & 0x0110); return static_cast<uint8_t>(w | (w>>8)); }

или же

uint8_t reverse(uint8_t a) { unsigned w = ((a & 0x11) << 7) | ((a & 0x22) << 5) | ((a & 0x44) << 3) | ((a & 0x88) << 1); return static_cast<uint8_t>(w | (w>>8)); } Ответ №21unsigned char c ; // the original unsigned char u = // the reversed c>>7&0b00000001 | c<<7&0b10000000 | c>>5&0b00000010 | c<<5&0b01000000 | c>>3&0b00000100 | c<<3&0b00100000 | c>>1&0b00001000 | c<<1&0b00010000 ; Explanation: exchanged bits as per the arrows below. 01234567 <——> #<—-># ##<—>## ###<>### Ответ №22#include <stdio.h> #include <stdlib.h> #define BIT0 (0x01) #define BIT1 (0x02) #define BIT2 (0x04) #define BIT3 (0x08) #define BIT4 (0x10) #define BIT5 (0x20) #define BIT6 (0x40) #define BIT7 (0x80) #define BYTE_TO_BINARY_PATTERN «%c%c%c%c%c%c%c%cn» #define BITETOBINARY(byte) (byte & BIT7 ? ‘1’ : ‘0’), (byte & BIT6 ? ‘1’ : ‘0’), (byte & BIT5 ? ‘1’ : ‘0’), (byte & BIT4 ? ‘1’ : ‘0’), (byte & BIT3 ? ‘1’ : ‘0’), (byte & BIT2 ? ‘1’ : ‘0’), (byte & BIT1 ? ‘1’ : ‘0’), (byte & BIT0 ? ‘1’ : ‘0’) #define BITETOBINARYREVERSE(byte) (byte & BIT0 ? ‘1’ : ‘0’), (byte & BIT1 ? ‘1’ : ‘0’), (byte & BIT2 ? ‘1’ : ‘0’), (byte & BIT3 ? ‘1’ : ‘0’), (byte & BIT4 ? ‘1’ : ‘0’), (byte & BIT5 ? ‘1’ : ‘0’), (byte & BIT6 ? ‘1’ : ‘0’), (byte & BIT7 ? ‘1’ : ‘0’) int main() { int i,j,c; i |= BIT2|BIT7; printf(«0x%02Xn»,i); printf(BYTE_TO_BINARY_PATTERN,BITETOBINARY(i)); printf(«Reverse»); printf(BYTE_TO_BINARY_PATTERN,BITETOBINARYREVERSE(i)); return 0; } Ответ №23

Я добавлю свое решение, поскольку пока не могу найти ничего подобного в ответах. Возможно, он немного перегружен, но он генерирует таблицу поиска, используя С++ 14 std::index_sequence во время компиляции.

#include <array> #include <utility> constexpr unsigned long reverse(uint8_t value) { uint8_t result = 0; for (std::size_t i = 0, j = 7; i < 8; ++i, —j) { result |= ((value & (1 << j)) >> j) << i; } return result; } template<size_t… I> constexpr auto make_lookup_table(std::index_sequence<I…>) { return std::array<uint8_t, sizeof…(I)>{reverse(I)…}; } template<typename Indices = std::make_index_sequence<256>> constexpr auto bit_reverse_lookup_table() { return make_lookup_table(Indices{}); } constexpr auto lookup = bit_reverse_lookup_table(); int main(int argc) { return lookup[argc]; }

https://godbolt.org/z/cSuWhF

Ответ №24

Вот простое и удобочитаемое решение, переносимое на все совместимые платформы, в том числе с sizeof(char) == sizeof(int):

#include <limits.h> unsigned char reverse(unsigned char c) { int shift; unsigned char result = 0; for (shift = 0; shift < CHAR_BIT; shift++) { result <<= 1; result |= c & 1; c >>= 1; } return result; } Ответ №25

Я знаю, что этот вопрос устарел, но я все еще думаю, что тема актуальна для некоторых целей, и вот версия, которая работает очень хорошо и читаема. Я не могу сказать, что это самый быстрый или самый эффективный, но он должен быть одним из самых чистых. Я также включил вспомогательную функцию для простого отображения битовых комбинаций. Эта функция использует некоторые стандартные библиотечные функции вместо написания вашего собственного битового манипулятора.

#include <algorithm> #include <bitset> #include <exception> #include <iostream> #include <limits> #include <string> // helper lambda function template template<typename T> auto getBits = [](T value) { return std::bitset<sizeof(T) * CHAR_BIT>{value}; }; // Function template to flip the bits // This will work on integral types such as int, unsigned int, // std::uint8_t, 16_t etc. I did not test this with floating // point types. I chose to use the ‘bitset’ here to convert // from T to string as I find it easier to use than some of the // string to type or type to string conversion functions, // especially when the bitset has a function to return a string. template<typename T> T reverseBits(T& value) { static constexpr std::uint16_t bit_count = sizeof(T) * CHAR_BIT; // Do not use the helper function in this function! auto bits = std::bitset<bit_count>{value}; auto str = bits.to_string(); std::reverse(str.begin(), str.end()); bits = std::bitset<bit_count>(str); return static_cast<T>( bits.to_ullong() ); } // main program int main() { try { std::uint8_t value = 0xE0; // 1110 0000; std::cout << +value << ‘n’; // don’t forget to promote unsigned char // Here is where I use the helper function to display the bit pattern auto bits = getBits<std::uint8_t>(value); std::cout << bits.to_string() << ‘n’; value = reverseBits(value); std::cout << +value << ‘n’; // + for integer promotion // using helper function again… bits = getBits<std::uint8_t>(value); std::cout << bits.to_string() << ‘n’; } catch(const std::exception& e) { std::cerr << e.what(); return EXIT_FAILURE; } return EXIT_SUCCESS; }

И это дает следующий вывод.

224 11100000 7 00000111 Ответ №26#define BITS_SIZE 8 int reverseBits ( int a ) { int rev = 0; int i; /* scans each bit of the input number*/ for ( i = 0; i < BITS_SIZE — 1; i++ ) { /* checks if the bit is 1 */ if ( a & ( 1 << i ) ) { /* shifts the bit 1, starting from the MSB to LSB * to build the reverse number */ rev |= 1 << ( BITS_SIZE — 1 ) — i; } } return rev; } Ответ №27 xor ax,ax xor bx,bx mov cx,8 mov al,original_byte! cycle: shr al,1 jnc not_inc inc bl not_inc: test cx,cx jz,end_cycle shl bl,1 loop cycle end_cycle:

обратный байт будет в регистре bl

Ответ №28

Как насчет этого…

int value = 0xFACE; value = ((0xFF & value << 8) | (val >> 8); Ответ №29

Это старый вопрос, но никто, кажется, не показал ясный легкий путь (самый близкий был edW). Я использовал С# для проверки этого, но в этом примере нет ничего такого, что не могло бы быть легко сделано в C.

void PrintBinary(string prompt, int num, int pad = 8) { Debug.WriteLine($»{prompt}: {Convert.ToString(num, 2).PadLeft(pad, ‘0’)}»); } int ReverseBits(int num) { int result = 0; int saveBits = num; for (int i = 1; i <= 8; i++) { // Move the result one bit to the left result = result << 1; //PrintBinary(«saveBits», saveBits); // Extract the right-most bit var nextBit = saveBits & 1; //PrintBinary(«nextBit», nextBit, 1); // Add our extracted bit to the result result = result | nextBit; //PrintBinary(«result», result); // We’re done with that bit, rotate it off the right saveBits = saveBits >> 1; //Debug.WriteLine(«»); } return result; } void PrintTest(int nextNumber) { var result = ReverseBits(nextNumber); Debug.WriteLine(«—————————————«); PrintBinary(«Original», nextNumber); PrintBinary(«Reverse», result); } void Main() { // Calculate the reverse for each number between 1 and 255 for (int x = 250; x < 256; x++) PrintTest(x); }

Оцените статью
Добавить комментарий