2008-08-29 3 views
33

Я знаю, что верно следующееЕсть ли способ выполнить круговое смещение бита в C#?

int i = 17; //binary 10001 
int j = i << 1; //decimal 34, binary 100010 

Но, если вы перемещаетесь слишком далеко, биты опадают конца. Там, где это происходит, речь идет о размере целого числа, с которым вы работаете.

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

+0

Где можно было бы использовать операцию такого типа? Какова цель создания бит-поворота? Мне не нужно знать, но меня просто интересует постоянно расширяющееся знание. Keith – 2008-10-07 14:32:31

+0

очень хороший вопрос. Я просто проверил сгенерированный код, и компилятор C# не генерирует код, который использует команды вращения процессора (не то, что архитектура x86 имеет их с 8086 ...). Это позор. C делает эту оптимизацию. Также вращение очень важно для задач криптографии и dsp. – 2009-06-08 01:45:30

ответ

45

Если вы знаете размер типа, вы могли бы сделать что-то вроде:

uint i = 17; 
uint j = i << 1 | i >> 31; 

... который будет выполнять циклический сдвиг на 32 битное значение.

В качестве обобщения к циклическому сдвигу влево N бит, на переменном битовые б:

/*some unsigned numeric type*/ input = 17; 
var result = input << n | input >> (b - n); 


@The комментарий, оказывается, что С # не лечить старший бит подписанных значений по-разному. Я нашел информацию об этом here. Я также изменил пример использования uint.

9

Один года назад Я реализовать MD4 для моего дипломную. Здесь это моя реализация кругового сдвига бит с использованием UInt32.

private UInt32 RotateLeft(UInt32 x, Byte n) 
{ 
     return UInt32((x << n) | (x >> (32 - n))); 
} 
3

Так же, как ссылки о том, как это сделать, это две функции работают отлично для вращения биты 1/2word:

static public uint ShiftRight(uint z_value, int z_shift) 
{ 
    return ((z_value >> z_shift) | (z_value << (16 - z_shift))) & 0x0000FFFF; 
} 

static public uint ShiftLeft(uint z_value, int z_shift) 
{ 
    return ((z_value << z_shift) | (z_value >> (16 - z_shift))) & 0x0000FFFF; 
} 

Было бы легко расширить его для любого заданного размера.

0

Самое известное приложение - решение проблемы Иосифа Флавия (как описано в Конкретной математике, см. http://oeis.org/A006257). Это в основном головоломка без очевидных приложений. В this video я продемонстрировал связи между проблемой второго порядка Иосифа и полными сбалансированными деревьями. Это все еще не приложение, но слегка двигающееся в правильном направлении.