Двоичный сдвиг вправо, учитывая только сложение

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

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

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

Любое понимание будет оценено.


person DivinusVox    schedule 31.03.2011    source источник


Ответы (4)


Используя AND, вы можете установить все биты равными нулю, кроме последнего значимого полубайта:

0101010111010101
0000000000001111 AND
----------------
0000000000000101

Сдвинув все это правильно, вы можете прочитать следующий фрагмент:

0101010111010101 SHR 4
----------------
    010101011101
0000000000001111 AND
----------------
0000000000001101

Вам это полезно?

person C.Evenhuis    schedule 31.03.2011
comment
Уже применяя маскирование, чтобы очистить несущественные биты. Проблема, с которой я сталкиваюсь, заключается в том, что в языке нет операции сдвига вправо. Нужно выяснить, как создать эту операцию путем добавления целого числа со знаком к 16-битному значению. Что я делаю в данный момент, так это маскирую значение, проверяя 1 в бите 15, и, если он присутствует, сдвиг влево и добавление 1, иначе сдвиг влево. Это кажется действительно неэффективным, и мне приходится создавать подпрограмму для каждого кусочка в этом методе. - person DivinusVox; 31.03.2011

У вас есть адд с переносом? Вместо теста на отрицательный добавьте бит с конца и добавьте ноль с переносом, чтобы вернуть его справа. особо не экономит. Пока я не могу придумать другое решение, сдвиньте влево, немного протестируйте, если установлено, добавьте 1 к чему-то и сдвиньте это что-то:

uint a,b,i;

b=0;
for(i=0;i<4;i++)
{
   b=b+b;
   if(a&0x8000) b+=1;
   a=a+a;
}

Если бы uint выше было 16 бит, тогда это дало бы вам сдвиг вправо на 12. a было бы уничтожено в процессе создания b, как написано.

person old_timer    schedule 31.03.2011
comment
Нет доп с переносом. знак равно - person DivinusVox; 01.04.2011

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

unsigned rez, tmp;
for (rez = 0, tmp = some_word & 0x0FFF; tmp != some_word; rez++, tmp += 0x1000);
person ruslik    schedule 31.03.2011

Так что оригинальный метод, который я использовал, сработал. Я также придумал еще один, на случай, если у кого-нибудь снова возникнет эта проблема.

Я создал подпрограмму, которая оценивает 4 бита за раз и создает число на основе оценки, для некоторого псевдокода в стиле C это выглядит так:

16bitSignedInt bin; //binary being analyzed
int value; //number being built

for (int i = 0; i < 4; i++) // while 0-3, for each nibble of the 16 bits
{
   if (bin.bit15 = 1)
      value += 8; // dominate bit in nibble

   bin <<= 1; // left shift 1

   if (bin.bit15 = 1)
      value += 4; // 2nd bit in nibble

   bin <<= 1; // left shift 1

   if (bin.bit15 = 1)
      value += 2; // 3rd bit in nibble

   bin <<= 1; // left shift 1

   if (bin.bit15 = 1)
      value += 1; // last bit in nibble

   bin <<= 1; // left shift 1

   //do work with value
}

Грубо, но эффективно.

person DivinusVox    schedule 02.04.2011