Оператор минус используется как унарная побитовая операция - PullRequest
0 голосов
/ 03 февраля 2019

Я не совсем понимаю, как оператор "-" влияет на следующий код:

#define COMP(x) ((x) & -(x))

unsigned short a = 0xA55A;
unsigned short b = 0x0400;

Может кто-нибудь объяснить, что такое COMP (a) и COMP (b) и как они рассчитываются?

Ответы [ 4 ]

0 голосов
/ 03 февраля 2019

В основном, то, что делает COMP - это И два операнда, один из которых находится в своей исходной форме, а один - отрицание своей формы.

Как ЦП обычно обрабатывают числа со знаком, использует 2Дополнение , дополнение 2 разбивает диапазон числового типа данных на 2, из которых (2 ^ n-1) -1 положительно, а (2 ^ n-1) отрицательно.

MSB(самый правый бит) представляет знак числовых данных

например,

0111 -> +7
0110 -> +6
0000 -> +0
1111 -> -1
1110 -> -2
1100 -> -6

Итак, что делает COMP, выполняя И на положительной и отрицательной версии числовых данных, чтобы получитьLSB (самый левый бит) первого 1.

Я написал пример кода, который может помочь вам понять здесь: http://coliru.stacked -crooked.com / a / 935c3452b31ba76c

0 голосов
/ 03 февраля 2019

знак "-" отрицает значение короткого параметра в дополнении до двух .(короче, поверните все от 0 до 1, от 1 до 0, а затем добавьте 1)

, поэтому 0xA55A в двоичном виде - это 1010 0101 0101 1010
, затем - (0xA55A) в двоичном виде - 0101 1010 1010 0110
пробег & между ними даст вам 0000 0000 0000 0010

0 голосов
/ 03 февраля 2019

-(x) отрицает x.Отрицание в дополнении к двум - это то же самое, что и ~x+1 (bitflip + 1), как показано в приведенном ниже коде:

#include <stdio.h>
#include <stdio.h>
#include <stdint.h>
int prbits(uintmax_t X, int N /*how many bits to print (from the low end)*/)
{
    int n=0;
    uintmax_t shift=(uintmax_t)1<<(N-1);
    for(;shift;n++,shift>>=1) putchar( (X&shift)?'1':'0');
    return n;
}
int main()
{
    prbits(0xA55A,16),puts("");
    //1010010101011010

    prbits(~0xA55A,16),puts("");
    //0101101010100101

    prbits(~0xA55A+1,16),puts("");
    //0101101010100110
    prbits(-0xA55A,16),puts("");
    //0101101010100110 (same)

}

Когда вы разбиваете бит на значение с его битовым значением, вы получаете 0. Когда вы разбиваете бит на значениес его значением bitfliped + 1 (= его отрицательное значение) вы получаете первый ненулевой бит справа.

Почему?Если самый правый бит ~x равен 1, добавление 1 к нему даст 0 с carry=1.Вы повторяете это, в то время как самые правые биты равны 1 и обнуляют эти биты.Как только вы достигнете нуля (который будет 1 в x, поскольку вы добавляете 1 к ~x), он превращается в 1 с переносом == 0, поэтому сложение заканчивается.Справа у вас нули, слева у вас битфлипы.Вы удаляете это с оригиналом и получаете первый ненулевой бит справа.

0 голосов
/ 03 февраля 2019

(x) & -(x) равен младшему биту, установленному в x при использовании дополнения 2 для представления двоичных чисел.

Это означает COMP(a) == 0x0002; и COMP(b) == 0x0400;

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