Как сделать одинарное и / или уменьшение шины до немного в Perl? - PullRequest
0 голосов
/ 14 мая 2019

У меня есть переменная $A = 0x3;

Я хочу, чтобы $B был одним, т. Е. Со всеми битами переменной A

Также как мне сделать то же самое с OR?

Уже пробовал $B &= $A, не работает.

Ответы [ 4 ]

3 голосов
/ 14 мая 2019

Если $A является 8-битным значением, и если вы хотите использовать И все 8 битов друг с другом, вы всегда получите 0, если все 8 бит не равны 1

+----+----+----+----+----+----+----+----+---------------------------------------+
| A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 | A7 & A6 & A5 & A4 & A3 & A2 & A1 & A0 |
+----+----+----+----+----+----+----+----+---------------------------------------+
|  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |                                     0 |
+----+----+----+----+----+----+----+----+---------------------------------------+
|  0 |  0 |  0 |  0 |  0 |  0 |  0 |  1 |                                     0 |
+----+----+----+----+----+----+----+----+---------------------------------------+
|  0 |  0 |  0 |  0 |  0 |  0 |  1 |  0 |                                     0 |
+----+----+----+----+----+----+----+----+---------------------------------------+
|  0 |  0 |  0 |  0 |  0 |  0 |  1 |  1 |                                     0 |
+----+----+----+----+----+----+----+----+---------------------------------------+
|  0 |  0 |  0 |  0 |  0 |  1 |  0 |  0 |                                     0 |
+----+----+----+----+----+----+----+----+---------------------------------------+
...
+----+----+----+----+----+----+----+----+---------------------------------------+
|  1 |  1 |  1 |  1 |  1 |  1 |  1 |  0 |                                     0 |
+----+----+----+----+----+----+----+----+---------------------------------------+
|  1 |  1 |  1 |  1 |  1 |  1 |  1 |  1 |                                     1 |
+----+----+----+----+----+----+----+----+---------------------------------------+

Это означает, что вы получите 0, если $A не равно 0b11111111 aka 0xFF aka 255. Это означает, что вы можете просто использовать следующее:

my $B = $A == 255 ? 1 : 0;

Вышеупомянутое решение намного проще и быстрее, чем использование побитовых операций, но их можно использовать.

Чтобы выделить немного, используется следующее:

( $A >> $bitnum ) & 1

Таким образом, следующее будет И 8 бит вместе:

my $B =
     ( ( $A >> 7 ) & 1 )
   & ( ( $A >> 6 ) & 1 )
   & ( ( $A >> 5 ) & 1 )
   & ( ( $A >> 4 ) & 1 )
   & ( ( $A >> 3 ) & 1 )
   & ( ( $A >> 2 ) & 1 )
   & ( ( $A >> 1 ) & 1 )
   & ( ( $A >> 0 ) & 1 );

Удаление избыточного & 1 дает нам следующее упрощенное решение:

my $B = 1
   & ( $A >> 7 )
   & ( $A >> 6 )
   & ( $A >> 5 )
   & ( $A >> 4 )
   & ( $A >> 3 )
   & ( $A >> 2 )
   & ( $A >> 1 )
   & ( $A >> 0 );

Фактически, поскольку мы начинаем с 8-битного значения, достаточно следующего:

my $B =
     ( $A >> 7 )
   & ( $A >> 6 )
   & ( $A >> 5 )
   & ( $A >> 4 )
   & ( $A >> 3 )
   & ( $A >> 2 )
   & ( $A >> 1 )
   & ( $A >> 0 );

Мы можем улучшить это, добавив несколько битов одновременно!

 my $B = $A;
 $B &= $B >> 4;
 $B &= $B >> 2;
 $B &= $B >> 1;
2 голосов
/ 14 мая 2019

Не уверен, что " не работает " (или что вы спрашиваете?)

Как работает этот пример

perl -wE'
    $v=0x3; $u = 0b010;
    printf "%6s = %#6b ($v)\n", "v", $v;
    printf "%6s = %#6b ($u)\n", "u", $u; 
    $r = $v & $u; 
    printf "%6s = %#6b ($r)\n", "v & u", $r'

относятся к тому, что вы делаете?

печатает

     v =   0b11 (3)
     u =   0b10 (2)
 v & u =   0b10 (2)
0 голосов
/ 15 мая 2019

Если вы хотите объединить биты с точностью до 1 старшего разряда,

+----+----+----+----+----+----+----+----+-------------------------------------------+
| A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 |                                           |
+----+----+----+----+----+----+----+----+-------------------------------------------+
|  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |                                         0 |
+----+----+----+----+----+----+----+----+-------------------------------------------+
|  0 |  0 |  0 |  0 |  0 |  0 |  0 |  1 |                                    A0 = 1 |
+----+----+----+----+----+----+----+----+-------------------------------------------+
|  0 |  0 |  0 |  0 |  0 |  0 |  1 |  0 |                               A1 & A0 = 0 |
+----+----+----+----+----+----+----+----+-------------------------------------------+
|  0 |  0 |  0 |  0 |  0 |  0 |  1 |  1 |                               A1 & A0 = 1 |
+----+----+----+----+----+----+----+----+-------------------------------------------+
|  0 |  0 |  0 |  0 |  0 |  1 |  0 |  0 |                          A2 & A1 & A0 = 0 |
+----+----+----+----+----+----+----+----+-------------------------------------------+
...
+----+----+----+----+----+----+----+----+-------------------------------------------+
|  1 |  1 |  1 |  1 |  1 |  1 |  1 |  0 | A7 & A6 & A5 & A4 & A3 & A2 & A1 & A0 = 0 |
+----+----+----+----+----+----+----+----+-------------------------------------------+
|  1 |  1 |  1 |  1 |  1 |  1 |  1 |  1 | A7 & A6 & A5 & A4 & A3 & A2 & A1 & A0 = 1 |
+----+----+----+----+----+----+----+----+-------------------------------------------+

Я бы использовал таблицу поиска, если вы сделали это несколько раз.

my @B = (0) x 256;  $B[$_] = 1 for 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF;

my $B = $B[$A];

Вы также можете использовать решение моба .

my $B = ( $A & ($A+1) ) ? 0 : 1;
0 голосов
/ 14 мая 2019
$B = 0+!($A & ($A+1));

Если $A = 2 n -1 для некоторых n , то $A & ($A+1) будет равно 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...