Відповіді:
Пам'ятайте, що негативні числа зберігаються як доповнення двох позитивних аналогів. Як приклад, ось подання -2 у двох доповненнях: (8 біт)
1111 1110
Як ви це отримаєте, це взяти двійкове представлення числа, взяти його доповнення (перевернути всі біти) та додати одне. Два починається як 0000 0010, і перевернувши біти, ми отримаємо 1111 1101. Якщо додати один, ми отримаємо результат вище. Перший біт - це бітовий знак, що передбачає негатив.
Тож давайте подивимось, як ми отримуємо ~ 2 = -3:
Ось ще два:
0000 0010
Просто переверніть всі біти і ми отримаємо:
1111 1101
Ну, як виглядає -3 у доповненні двох? Почніть з позитивного 3: 0000 0011, переверніть всі біти до 1111 1100 і додайте один, щоб стати від’ємним значенням (-3), 1111 1101.
Отже, якщо ви просто інвертуєте біти в 2, ви отримаєте їхнє додаткове представлення -3.
~ перевертає біти у значення.
Чому ~2це -3стосується того, як числа представлені порозрядно. Числа представлені як доповнення двох .
Отже, 2 - двійкове значення
00000010
І ~ 2 перевертає біти, тому значення тепер:
11111101
Що, є двійкове представлення -3.
Як згадували інші, ~просто перевернуті біти (змінюється один на нуль і нуль на один) і з двох доповнюють ви отримуєте результат, який ви побачили.
Одне слід додати, чому використовується доповнення двох, це так, що операції над від’ємними числами будуть такими ж, як і на додатних числах. Подумайте, -3як число, до якого 3слід додати нуль, і ви побачите, що це число 1101, пам’ятайте, що двійкове додавання - це як базове шкільне (десяткове) додавання, яке ви переносите лише на два, а не на 10 .
1101 +
0011 // 3
=
10000
=
0000 // lose carry bit because integers have a constant number of bits.
Тому 1101це -3, фліп біти , які Ви отримуєте , 0010який є два.
Я знаю, що відповідь на це питання розміщена ще довго, але я хотів поділитися своєю відповіддю за те саме.
Для пошуку доповнення чисельного числа спочатку знайдіть його двійковий еквівалент. Тут десяткове число 2представлено як 0000 0010у двійковій формі. Тепер беремо його доповнення, перевернувши (перевернувши всі 1 у 0 і всі 0 в 1) усі цифри його двійкового подання, що призведе до:
0000 0010 → 1111 1101
Це доповнення десяткового числа 2. А оскільки перший біт, тобто біт знака дорівнює 1 у двійковому числі, це означає, що знак є негативним для числа, яке він зберігає. (тут вказане число не 2, а доповнене число 2).
Тепер, оскільки числа зберігаються як доповнення 2 (беручи доповнення числа плюс одне), щоб відобразити це двійкове число 1111 1101, у десятковій формі , спершу нам потрібно знайти його 2 доповнення, яке буде:
1111 1101 → 0000 0010 + 1 → 0000 0011
Це доповнення 2-х. Десяткове подання двійкового числа, 0000 0011є 3. І, оскільки бітовий знак був один, як було сказано вище, тому отримана відповідь така -3.
Підказка: Якщо ви уважно читаєте цю процедуру, то ви б помітили, що результатом для оператора комплементу є насправді, число (операнд - до якого застосовується цей оператор) плюс одне з негативним знаком. Ви можете спробувати це і з іншими номерами.
add, flip, add. 0010-> 0011-> 1100->1101
0010 1101 0010
NOT 0 = 1і NOT 1 = 0. У чотирибітній системі NOT 0011(3) = 1100(12 без знаків, -4 підписано). Як я розумію, доповнення двох визначається як (NOT n) + 1і використовується для пошуку негативного аналога числа незалежно від кількості бітів. Таким чином, 2c(5) = -5. Бачите, зараз це має ідеальний сенс. До тих пір, як ви називаєте цю операцію, що це: побіжно НЕ.
int a = 4; System.out.println (~ a); Результат буде: -5
'~' будь-якого цілого числа в java являє собою доповнення 1 числа no. наприклад, я беру ~ 4, що означає в двійковому поданні 0100. По-перше, довжина цілого числа становить чотири байти, тобто 4 * 8 (8 біт за 1 байт) = 32. Отже, в системній пам'яті 4 представлено як 0000 0000 0000 0000 0000 0000 0000 0100 зараз ~ оператор виконує доповнення 1 на вищевказаному двійковому номері
тобто 1111 1111 1111 1111 1111 1111 1111 1011-> 1 є доповненням найбільш значущий біт являє собою знак no (або - або +), якщо він 1, тоді знак є "-", якщо це 0, тоді знак є "+" відповідно до це наш результат - від'ємне число, у java від'ємні числа зберігаються у формі 2 доповнення, набутий результат ми маємо перетворити у 2 доповнення (спочатку виконаймо доповнення 1 та просто додай 1 до 1 доповнення). всі вони стануть нулями, крім найбільш значущого біта 1 (який є нашим знаковим поданням числа, що означає залишки 31 біт 1111 1111 1111 1111 1111 1111 1111 1011 (отриманий результат ~ оператора) 1000 0000 0000 0000 0000 0000 0000 0000 0100 (додаток 1)
1000 0000 0000 0000 0000 0000 0000 0101 зараз результат -5 перевірте це посилання на відео <[Біт мудрі оператори в Java] https://youtu.be/w4pJ4cGWe9Y
Просто ...........
Як доповнення 2 до будь-якого числа, ми можемо обчислити, перевернувши всі 1 на 0 і навпаки, ніж додамо до нього 1.
Тут N = ~ N дає результати - (N + 1) завжди. Оскільки система зберігає дані у формі доповнення 2, це означає, що вона зберігає ~ N так.
~N = -(~(~N)+1) =-(N+1).
Наприклад::
N = 10 = 1010
Than ~N = 0101
so ~(~N) = 1010
so ~(~N) +1 = 1011
Тепер точка - звідки походить Мінус. Моя думка, припустимо, у нас є 32-розрядний реєстр, що означає 2 ^ 31 -1 біт, що бере участь в роботі, і для відпочинку один біт, який змінюється в попередніх обчисленнях (доповненнях), зберігається як біт знаків, який зазвичай 1. І отримаємо результат як ~ 10 = -11.
~ (-11) = 10;
Вищезазначене справедливо, якщо printf ("% d", ~ 0); отримуємо результат: -1;
Але printf ("% u", ~ 0), ніж результат: 4294967295 на 32-бітній машині.
Оператор побітового доповнення (~) є одинарним оператором.
Він працює відповідно до наступних методів
Спочатку він перетворює задане десяткове число у відповідне двійкове значення. У випадку 2 він спочатку перетворює 2 до 0000 0010 (у 8 бітне двійкове число).
Тоді він перетворює всі 1 в число в 0, а всі нулі в 1; тоді число стане 1111 1101.
тобто 2-х доповнення представлення -3.
Для того, щоб знайти неподписане значення за допомогою доповнення, тобто просто перетворити 1111 1101 в десятковий (= 4294967293), ми можемо просто використовувати% u під час друку.
Я думаю, що для більшості людей частина плутанини походить від різниці між десятковим числом і підписаним двійковим числом, тому давайте уточнимо його спочатку:
для людського десяткового світу: 01 означає 1, -01 означає -1, для двійкового світу комп'ютера: 101 означає 5, якщо він не підписаний. 101 означає (-4 + 1), якщо він підписаний, коли підписана цифра знаходиться в положенні x. | х
тому перевернутий біт 2 = ~ 2 = ~ (010) = 101 = -4 + 1 = -3, плутанина виникає в результаті змішування підписаного результату (101 = -3) та несигналізованого результату (101 = 5)
tl; dr ~ перегортає шматочки. В результаті знак змінюється. ~2- від’ємне число ( 0b..101). Для виведення негативних чисел rubyдруку -, а потім два доповнення ~2:-(~~2 + 1) == -(2 + 1) == 3 . Позитивні числа виводяться як є.
Є внутрішнє значення та його рядкове подання. Для натуральних чисел вони в основному збігаються:
irb(main):001:0> '%i' % 2
=> "2"
irb(main):002:0> 2
=> 2
Останній еквівалентний:
irb(main):003:0> 2.to_s
"2"
~гортає біти внутрішнього значення. 2є 0b010. ~2є 0b..101. Дві крапки ( ..) представляють нескінченну кількість 1s. Оскільки найзначніший біт (MSB) результату 1, результат - від’ємне число ( (~2).negative? == true). Для виведення негативних чисел rubyдруку -, а потім два доповнюють внутрішнє значення. Доповнення двох обчислюється перегортанням бітів, а потім додаванням 1. Доповненням двох 0b..101є 3. Як такий:
irb(main):005:0> '%b' % 2
=> "10"
irb(main):006:0> '%b' % ~2
=> "..101"
irb(main):007:0> ~2
=> -3
Підсумовуючи це, він перегортає шматочки, що змінює знак. Щоб вивести негативне число, яке воно друкує -, тоді ~~2 + 1( ~~2 == 2).
Причина rubyвиведення негативних чисел на кшталт цього полягає в тому, що вона розглядає збережене значення як доповнення двох до абсолютного значення. Іншими словами, зберігається те, що зберігається 0b..101. Це від’ємне число, і як таке - це доповнення якоїсь дві величини x. Щоб знайти x, це два доповнення 0b..101. Що є двома доповненнями двох доповненнями x. Що є x(наприклад ~(~2 + 1) + 1 == 2).
Якщо ви звернетесь ~до негативного числа, воно просто переверне біти (що все-таки змінить знак):
irb(main):008:0> '%b' % -3
=> "..101"
irb(main):009:0> '%b' % ~-3
=> "10"
irb(main):010:0> ~-3
=> 2
Більш заплутаною є те, що ~0xffffff00 != 0xff(або будь-яке інше значення з MSB рівне 1). Давайте спростимо це небагато: ~0xf0 != 0x0f. Це тому, що це трактує 0xf0як позитивне число. Що насправді має сенс. Так, ~0xf0 == 0x..f0f. Результат - від’ємне число. Доповненням двох 0x..f0fє 0xf1. Так:
irb(main):011:0> '%x' % ~0xf0
=> "..f0f"
irb(main):012:0> (~0xf0).to_s(16)
=> "-f1"
У разі , якщо ви не збираєтеся застосовувати оператори побітового до результату, ви можете розглянути в ~якості -x - 1оператора:
irb(main):018:0> -2 - 1
=> -3
irb(main):019:0> --3 - 1
=> 2
Але це, мабуть, не надто корисне.
Приклад Скажімо, вам дають 8-бітну (для простоти) маску, і ви хочете обчислити кількість 0s. Ви можете їх обчислити, перегортаючи біти і викликаючи bit_length( 0x0f.bit_length == 4). Але ~0xf0 == 0x..f0f, таким чином, ми повинні вирізати непотрібні шматочки:
irb(main):014:0> '%x' % (~0xf0 & 0xff)
=> "f"
irb(main):015:0> (~0xf0 & 0xff).bit_length
=> 4
Або ви можете скористатися оператором XOR ( ^):
irb(main):016:0> i = 0xf0
irb(main):017:0> '%x' % i ^ ((1 << i.bit_length) - 1)
=> "f"
Спочатку ми повинні розділити дану цифру на її двійкові цифри, а потім відмінити її, додавши в останню двійкову цифру. Після цього виконання ми повинні дати протилежний знак попередній цифрі тому, що ми знаходимо в комплектації ~ 2 = -3 Пояснення : 2s двійкова форма 00000010 змінюється на 11111101 це доповнення, потім завершене 00000010 + 1 = 00000011, що є двійковою формою з трьох і з -знаком Ie, -3
Бітовий оператор - це одинарний оператор, який працює за методом знаків та величин відповідно до мого досвіду та знань.
Наприклад, ~ 2 призведе до -3.
Це тому, що бітовий оператор спочатку представляє число в знаку та величині, яке становить 0000 0010 (8-бітний оператор), де MSB - біт знаків.
Тоді пізніше знадобиться від'ємне число 2, яке становить -2.
-2 представлений як 1000 0010 (8-бітний оператор) за знаком і величиною.
Пізніше він додає 1 до LSB (1000 0010 + 1), що дає вам 1000 0011.
Що становить -3.
Javascript tilde (~) примушує задане значення доповнювати - всі біти перевернуті. Це все робить тильда. Це не знак впевненості. Він ні додає, ні віднімає жодної кількості.
0 -> 1
1 -> 0
...in every bit position [0...integer nbr of bits - 1]
У стандартних настільних процесорах, що використовують мови високого рівня, такі як JavaScript, арифметика з підписом BASE10 є найпоширенішою, але майте на увазі, це не єдиний вид. Біти на рівні процесора підлягають інтерпретації на основі ряду факторів. На рівні «коду» в цьому випадку JavaScript інтерпретуються за визначенням як 32-бітове ціле число (не залишаємо поплавці поза цим). Подумайте про це як квантові, ці 32-бітні представляють багато можливих значень одночасно. Це повністю залежить від перетворювальної лінзи, через яку ви їх переглядаєте.
JavaScript Tilde operation (1's complement)
BASE2 lens
~0001 -> 1110 - end result of ~ bitwise operation
BASE10 Signed lens (typical JS implementation)
~1 -> -2
BASE10 Unsigned lens
~1 -> 14
Все вищезазначене одночасно вірно.