Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Побитовое NOT. (https://javascript.ru/forum/misc/29860-pobitovoe-not.html)

9xakep 14.07.2012 11:25

Побитовое NOT.
 
Побитовое not заменяет каждый бит операнда на противоположенный:
// 0000 - это ноль
alert(~0) // -1
// Но если заменить каждый бит на противоположенный: 1111 - 15.
// Почему так?

P.S. почему же тогда ~ работает как: -(х+1) ??

Deff 14.07.2012 11:38

Заменяет каждый бит операнда включая знаковый

9xakep 14.07.2012 11:40

Deff,
эм..немного не понял

Deff 14.07.2012 11:40

alert(~1) // -1

9xakep 14.07.2012 12:36

Deff,
О_О
Вообще-то -2)
Так-с, я могу сейчас глупость сказать, но знаковый бит, это самый первый?

Все спасибо, приблизительно понял

Deff 14.07.2012 12:48

Цитата:

Сообщение от 9xakep
это самый первый?

Да - именно так
Цитата:

Сообщение от 9xakep
Вообще-то -2)

(*-1 Эт Ваша строка - скопировал без правки

x-yuri 14.07.2012 13:24

не то чтобы доказательство, но может прояснит немного картину:
  • Переполнение. Целочисленные переменные (в javascript такие "возникают" во время побитовых операций) имеют фиксированный размер. Если прибавить очень большое число, непоместившиеся биты "обрежуться", в частности (правила по аналогии с десятичной системой):
    Код:

    0101b
    +
    10000b
    ------
     0101b

  • Дополнительный код (дополнение до двух) - распространенный формат, в котором хранятся отрицательные числа. Половина значений отводятся под положительные числа, половина - под отрицательные:
    Код:

    1000b (-8) .. 1111b (-1), 0000b, 0001b (1) .. 0111b (7)
    Соответственно, чтобы получить отрицательное число, надо вычесть модуль из нуля, или, что то же самое, из 10000b (16) (в случае 4-битных чисел, в общем случае из 2^N, где N - количество битов):
    Код:

    10000b
    -
     0010b
    -------
     1110b

  • Дополнение до единицы - еще один формат, нераспространенный. Модуль числа получается с помощью операции NOT, например:
    Код:

    ~0001b = 1110b
    ~0010b = 1101b

    т.е. получается следующая картина:
    Код:

    1000b (-7) .. 1110b (-1), 1111b (-0), 0000b, 0001b (1) .. 0111b (7)
    и 1) отрицательные числа как бы смещены на один влево, 2) на образовавшемся месте появился отрицательный ноль
  • ~a = 1111b - a (хз, почему так получается), 1111b = (10000b - 1) ("разница" между форматами равна единице)
    Код:

    1111b
    -
    0001b
    -----
    1110b


Deff 14.07.2012 13:40

Вообще побитовая инверсия равна вычитанию из -1

alert(~2) // -3
alert(~3) // -4
alert(~4) // -5

9xakep 14.07.2012 16:39

Не, нуприблизительлно я все-таки понял, возьмем 4 бита:
0001 = 1
~0001 = 1110 = -2, проверим это:
1111 = -1,
1110+
1111
====
1101 = -3, т.к. 0101 = 3, у нас 4 бита, 1 бит - знаковость, значит 1101 = -3
чтд: 1110 = -2

Только у меня последний вопрос, скорее из части информатики:
Почему -1, это 1111, а не 1001 (если 4 бита)?

9xakep 14.07.2012 16:45

x-yuri,
Спасибо, но я мало что понял). Что значит b, в конце каждого числа?

devote 14.07.2012 16:58

Цитата:

Сообщение от 9xakep
Что значит b, в конце каждого числа?

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

x-yuri 14.07.2012 17:01

Цитата:

Сообщение от 9xakep
Спасибо, но я мало что понял).

задавай вопросы

Цитата:

Сообщение от 9xakep
Только у меня последний вопрос, скорее из части информатики:
Почему -1, это 1111, а не 1001 (если 4 бита)?

Ну это же договоренность такая, неудобно так. В случае дополнительного кода положительные и отрицательные числа складываются одинаково. Если же взять твою альтернативную схему, несмотря на ее логичность что ли или прямолинейность: 1) положительные и отрицательные числа складываются по-разному, 2) с переполнением сложнее: в случае дополнительного кода просто отбрасываются или заимствуются дополнительные разряды (как при сложении/вычитании в столбик), а здесь как?
Код:

0111b (7)
+
0001b (1)
---------
1111b (-7)

либо если не переполнение, то что?

x-yuri 14.07.2012 17:08

а, я даже понял ответ на твой изначальный вопрос :)
Цитата:

Сообщение от 9xakep
почему же тогда ~ работает как: -(х+1) ??

т.е. почему ~a = -1 - a: -1 = 1111b в дополнительном коде; другими словами, надо доказать, что ~a + a = 1111b. Операция NOT меняет нули на единицы и единицы на нули. И если сложить два числа у которых напротив единицы - ноль и наоборот, получится число состоящее только из единиц.

9xakep 14.07.2012 17:35

Цитата:

Сообщение от x-yuri
задавай вопросы

ок, щас)

9xakep 14.07.2012 17:39

Цитата:

Сообщение от x-yuri
И если сложить два числа у которых напротив единицы - ноль и наоборот, получится число состоящее только из единиц.

Ага...
~0 = -1 + 0,
~0000 = -1 + 0
~0000 = -1
1111 = -1.
Все теперь понял)
===============
0000 = 0 <==> 
0001 = 1 <--> 1111 = -1
0010 = 2 <--> 1110 = -2
0011 = 3 <--> 1101 = -3
0100 = 4 <--> 1100 = -4
0101 = 5 <--> 1011 = -5
0110 = 6 <--> 1010 = -6
0111 = 7 <--> 1001 = -7
P.S. короче: нужно запомнить, что 1111 = -1, 1110 = -2
с числами -3, -4 есть логика (заменяем первый бит операнда)
После уже просто инверитурем предыдущее число в левом ряду, например:
-6 = ~5
-6 = ~0101
-6 = 1010

Цитата:

0111b (7)
+
0001b (1)
---------
1111b (-7)
?
0111b (7)
+
0001b (1)
--------
1000 (8)

x-yuri 14.07.2012 17:45

ну если выбрать не такой крайний случай, то получится
Код:

~0101 + 0101 = 1111
1010
+
0101
----
1111


devote 14.07.2012 18:21

Цитата:

Сообщение от 9xakep
P.S. короче: нужно запомнить, что 1111 = -1, 1110 = -2

это в том случае если числа со знаком, если же числа бес знаковые, то и числа будут иные. 1111 = 15, 1110 = 14

9xakep 14.07.2012 18:25

devote,
ну у меня 4 бит, это понятно, щас читаю, что написал x-yuri, как и сказал, задам вопросы)

9xakep 14.07.2012 19:19

x-yuri,
чувак, супер, нет вопросов, все понял :D


Часовой пояс GMT +3, время: 08:03.