Подтвердить что ты не робот

Объяснение побитового оператора NOT

Почему битовый оператор NOT (~ в большинстве языков) преобразует следующие значения:

-2 -> 1
-1 -> 0
0 -> -1
1 -> -2

Не следует -2 конвертировать в 2, 1 преобразовать в -1 и т.д.?

4b9b3361

Ответ 1

См. два дополнения для представления отрицательных целых чисел на многих языках. Как вы можете видеть, -2 представлен 1111110; если вы инвертируете все эти биты, вы получаете 0000001, то есть значение 1.

Ответ 2

Это помогает, если вы посмотрите на него в двоичном формате.

Прежде всего, как вы знаете, отрицательные числа выражаются как (максимально возможное беззнаковое число плюс 1 минус значение). Таким образом, -1 в 16-битовом целое, которое имеет наивысшее значение без знака 65535, будет 65536-1 = 65535, то есть 0xffff в шестнадцатеричном выражении или 1111 1111 1111 1111 в двоичном формате.

Итак:

1 в двоичном формате = 0000 0000 0000 0001

НЕ для всех бит приведет к 1111 1111 1111 1110. То, что в десятичной системе, равно 65534. А 65536 минус 65535 равно 1, поэтому это -1.

Ответ 3

Большинство (все?) современных архитектур используют два дополнения для представления целых чисел. Таким образом, побитовое NOT представляет собой дополнение целого числа минус единицы.

Ответ 4

Это связано с тем, что отрицательные числа представлены как биты. Для этого обычно используется Two Complements.

-2 в этом обозначении 1111110, которое отрицает 1

Ответ 5

Это связано с тем, что бит-мудрый оператор буквально инвертирует каждый бит в слове. Это НЕ строго арифметическая операция, это логическая операция.

-2 ==% 1110, ~ -2 == ~% 1110 =% 0001 == 1 -1 ==% 1111, ~ -1 == ~% 1111 =% 0000 == 0

и т.д.

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

Ответ 6

    Dim mask As Integer = -1
    '11111111111111111111111111111111

    For x As Integer = -3 To 3
        Dim i As Integer = x
        Debug.WriteLine("")
        Debug.WriteLine("'" & Convert.ToString(i, 2).PadLeft(32, "0"c) & " > Num = " & i.ToString)

        i = i Xor mask 'reverse the bits (same as Not)
        Debug.WriteLine("'" & Convert.ToString(i, 2).PadLeft(32, "0"c) & " > Not = " & i.ToString)

        i += 1 'convert to two complement
        Debug.WriteLine("'" & Convert.ToString(i, 2).PadLeft(32, "0"c) & " > 2 Comp = " & i.ToString)
    Next

    'debug results

    '11111111111111111111111111111101 > Num = -3
    '00000000000000000000000000000010 > Not = 2
    '00000000000000000000000000000011 > 2 Comp = 3

    '11111111111111111111111111111110 > Num = -2
    '00000000000000000000000000000001 > Not = 1
    '00000000000000000000000000000010 > 2 Comp = 2

    '11111111111111111111111111111111 > Num = -1
    '00000000000000000000000000000000 > Not = 0
    '00000000000000000000000000000001 > 2 Comp = 1

    '00000000000000000000000000000000 > Num = 0
    '11111111111111111111111111111111 > Not = -1
    '00000000000000000000000000000000 > 2 Comp = 0

    '00000000000000000000000000000001 > Num = 1
    '11111111111111111111111111111110 > Not = -2
    '11111111111111111111111111111111 > 2 Comp = -1

    '00000000000000000000000000000010 > Num = 2
    '11111111111111111111111111111101 > Not = -3
    '11111111111111111111111111111110 > 2 Comp = -2

    '00000000000000000000000000000011 > Num = 3
    '11111111111111111111111111111100 > Not = -4
    '11111111111111111111111111111101 > 2 Comp = -3