Объяснение побитового НЕ оператора - PullRequest
17 голосов
/ 28 ноября 2010

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

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

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

Ответы [ 7 ]

23 голосов
/ 28 ноября 2010

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

11 голосов
/ 28 ноября 2010

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

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

1 в двоичном виде = 0000 0000 0000 0001

НЕ для всех битов приведет к 1111 1111 1111 1110.В десятичном виде это 65534. И 65536 минус 65534 равно 2, так что это -2.

0 голосов
/ 27 ноября 2018

Числа в компьютерных системах хранятся как 2 дополнительных.Если число положительное, то 2 положительных числа одинаковы. Но для отрицательных чисел оно отличается.

1.-2 -> 1 Здесь -2 будет храниться в компьютере как 1110 (то есть 2 дополнения-2). Теперь ~ 1110 равно 0001. Поскольку 0001 является положительным числом, оно будет сохранено в компьютере как 0001 (т.е. 1)

2.-1 -> 0 Здесь -1 будет сохранено в компьютере как 1111(т. е. 2 дополняют -1). Теперь ~ 1111 равно 0000. Поскольку 0000 - положительное число, оно будет сохранено в компьютере как 0000 (т. е. 0)

0 -> -1 Здесь 0 будет храниться в компьютере как 0000 (т.е. дополнение 2 к 0). Число ~ от 0000 равно 1111. Поскольку 1111 является отрицательным числом, оно будет сохранено в компьютере как 0001 (т.е.-1) (поскольку MSB установлен на 1111, число будет отрицательным)

1 -> -2 Здесь 1 будет храниться в компьютере как 0001 (то есть, 2 дополняют 1).Теперь ~ 0001 равно 1110. Поскольку 1110 является отрицательным числом, оно будет сохранено в компьютере как 0010 (то есть-2) (поскольку MSB установлен на 1110, число будет отрицательным)

0 голосов
/ 29 ноября 2010
    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's complement
        Debug.WriteLine("'" & Convert.ToString(i, 2).PadLeft(32, "0"c) & " > 2's Comp = " & i.ToString)
    Next

    'debug results

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

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

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

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

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

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

    '00000000000000000000000000000011 > Num = 3
    '11111111111111111111111111111100 > Not = -4
    '11111111111111111111111111111101 > 2's Comp = -3
0 голосов
/ 28 ноября 2010

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

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

и т. Д.

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

0 голосов
/ 28 ноября 2010

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

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

0 голосов
/ 28 ноября 2010

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

...