Відповіді:
Пам'ятайте, що негативні числа зберігаються як доповнення двох позитивних аналогів. Як приклад, ось подання -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
. Дві крапки ( ..
) представляють нескінченну кількість 1
s. Оскільки найзначніший біт (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-бітну (для простоти) маску, і ви хочете обчислити кількість 0
s. Ви можете їх обчислити, перегортаючи біти і викликаючи 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
Все вищезазначене одночасно вірно.