Битовая операция, эквивалентная функции pop в PERL (удалить MSB)

Есть ли в Perl побитовый оператор, который действует как >>, но удаляет старший бит? Вроде того, как оператор >> чем-то похож на функцию shift(), я ищу битовый оператор, похожий на pop().

110110 вернет 10110

101 вернет 01

В конечном счете, я пытаюсь увидеть, является ли число в двоичной форме палиндромным (например, 11011, 111 или 1010101), поэтому в идеале оператор должен иметь способ вернуть бит, который он удаляет. Ничего страшного, если оператор этого не сделает, поскольку я мог бы сделать это математически, но в интересах чистоты кода было бы здорово, если бы он автоматически возвращал MSB. Для LSB я делаю

$LSB=$mynum-2*($mynum>>1);
$mynum>>=1;

person Jake Stevens-Haas    schedule 22.12.2010    source источник


Ответы (4)


Я не могу придумать более простой способ, чем просто сохранить его в виде строки:

my $bits = sprintf '%b', $num;
while ( $bits =~ s/(.)// ) {
    print "removed $1\n";
}

хотя тогда ваша проверка палиндрома просто

$bits eq reverse $bits
person ysth    schedule 22.12.2010

см. Как проверить, двоичное представление целого числа является палиндромом?

person Community    schedule 22.12.2010
comment
Знаете, я слишком долго искал что-то подобное, чтобы не найти. Что означает WORDSIZE в этом примере? - person Jake Stevens-Haas; 22.12.2010
comment
@Ranting_Raven, я разместил это на случай, если вы пропустили. WORDSIZE - это размер слова на вашей машине (я полагаю) - person ; 23.12.2010

Поскольку ваши значения имеют переменное количество битов, вам нужна битовая строка или битовый вектор. Проверьте Bit::Vector на CPAN — кажется чтобы все еще быть активным.

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

person hippietrail    schedule 22.12.2010

Я не знаю о Perl, но в C/C++ вы бы сделали это так:

unsigned flp2(unsigned x) {
   x = x | (x >> 1);
   x = x | (x >> 2);
   x = x | (x >> 4);
   x = x | (x >> 8);
   x = x | (x >>16);
   return x - (x >> 1);
}

unsigned most_significant_bit = flp2(my_number);
my_number &= most_significant_bit;

Предоставлено Hacker's Delight.

Обратите внимание, что для поиска старшего бита в ассемблере можно использовать BSR, в MSVC — _BitScanReverse, в GCC — _builtin_clz. Однако я не знаю простых высокоуровневых (и портативных) операторов. Языки развиваются намного медленнее, чем процессоры и компиляторы.

person martona    schedule 22.12.2010