Доповняльний код (англ. two’s complement, «доповнення до 2») — найпоширеніший спосіб подання від'ємних чисел у комп'ютерах. Дозволяє замість команди віднімання використовувати команду додавання, для знакових і беззнакових чисел, що зменшує вимоги до архітектури комп'ютера. Доповняльний код від'ємного числа можна отримати так: інвертувати модуль числа у двійковому вигляді («перше доповнення») і додати одиницю («друге доповнення») або відняти число від нуля. Математично доповняльний код Xдоп = 2N+1 — X, де X — число, яке треба представити у доповняльному коді, N — к-сть розрядів числа.
Найстарший біт | |||||||||
0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | = | 127 |
0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | = | 126 |
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | = | 2 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | = | 1 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | = | 0 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | = | −1 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | = | −2 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | = | −127 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | = | −128 |
Восьмирозрядні доповняльні коди
Подання від'ємного числа у доповняльному коді
При записі числа в доповняльному коді старший розряд є знаковим. Якщо його значення дорівнює 0, то в решті розрядів записане додатне двійкове число, що збігається з прямим кодом.
Двійкове 8-розрядне число зі знаком в доповняльному коді може представляти будь-яке ціле в діапазоні від -128 до +127. Якщо старший розряд дорівнює нулю, то найбільше ціле число, що може бути записане в останніх 7 розрядах, дорівнює , що дорівнює 127.
Приклади:
Десяткове відображення | Двійкове відображення (8 біт) | ||
---|---|---|---|
прямий | обернений | доповняльний | |
127 | 01111111 | 01111111 | 01111111 |
1 | 00000001 | 00000001 | 00000001 |
0 | 00000000 | 00000000 | 00000000 |
-0 | 10000000 | 11111111 | --- |
-1 | 10000001 | 11111110 | 11111111 |
-2 | 10000010 | 11111101 | 11111110 |
-3 | 10000011 | 11111100 | 11111101 |
-4 | 10000100 | 11111011 | 11111100 |
-5 | 10000101 | 11111010 | 11111011 |
-6 | 10000110 | 11111001 | 11111010 |
-7 | 10000111 | 11111000 | 11111001 |
-8 | 10001000 | 11110111 | 11111000 |
-9 | 10001001 | 11110110 | 11110111 |
-10 | 10001010 | 11110101 | 11110110 |
-11 | 10001011 | 11110100 | 11110101 |
-127 | 11111111 | 10000000 | 10000001 |
-128 | --- | --- | 10000000 |
Доповняльний код для десяткових чисел
Це саме можна використовувати і в комп'ютерному поданні десяткові числа: для кожного розряду цифра X замінюється на 9-X, і до одержаного числа додається 1. Наприклад, при використанні чотиризначних чисел -0081 замінюється на 9919 (9919 + 0081 = 0000, п'ятий розряд викидається).
При застосуванні тієї ж ідеї до звичної 10-кової системи числення вийде (наприклад, для гіпотетичного процесора, що використовує 10-ткову систему числення):
10-кова система числення ("простий" запис) | 10-кова система числення, доповняльний код |
---|---|
... | ... |
13 | 0013 |
12 | 0012 |
11 | 0011 |
10 | 0010 |
9 | 0009 |
8 | 0008 |
... | ... |
2 | 0002 |
1 | 0001 |
0 | 0000 |
-1 | 9999 |
-2 | 9998 |
-3 | 9997 |
-4 | 9996 |
... | ... |
-9 | 9991 |
-10 | 9990 |
-11 | 9989 |
-12 | 9988 |
... | ... |
Перетворення у доповняльний код
Перетворення числа з прямого коду в доповняльний здійснюється за таким алгоритмом.
- Якщо число, записане в прямому коді, додатне, то до нього дописується старший (знаковий) розряд, рівний 0, і на цьому перетворення закінчується;
- Якщо число, записане в прямому коді, від'ємне, то всі розряди числа (крім знакового) інвертуються, а до результату додається 1. До отриманого числа дописується старший (знаковий) розряд, рівний 1.
Приклад. Перетворимо від'ємне число -5, записане в прямому коді, в доповняльний.
Прямий код числа -5, взятого за модулем:
101
Інвертуємо всі розряди числа, отримуючи таким чином обернений код:
010
Додамо до результату 1
011
Допишемо зліва знаковий одиничний розряд
1011
Для зворотного перетворення використовується той же алгоритм. А саме:
1011
Інвертуємо всі розряди числа, отримуючи таким чином обернений код:
0100
Додамо до результату 1
0101
І перевіримо, додавши до доповняльного коду
0101 + 1011 = 10000, п'ятий розряд викидається.
Р-адичні числа
В системі p-адичних чисел зміна знаку числа здійснюється перетворенням числа в його доповняльний код. Наприклад, якщо використовується 5-кова система числення, то число, протилежне 1000 … (1), так само є 4444 …. (-1).
Арифметичні операції
Додавання
Додавання двох чисел у доповняльному коді не потребує додаткових дій якщо доданки мають протилежні знаки, у такому випадку знак суми визначається автоматично. Приклад додавання 15 та -5:
11111 111 (перенесення) 0000 1111 (15) + 1111 1011 (−5) =================== 0000 1010 (10)
Цей процес залежить від обмеження вісьмома бітами: перенесення до відсутнього дев'ятого найстаршого біту ігнорується, що повертає нам правильний результат 1010.
Найстарші два біти рядка перенесених цифр містять важливу інформацію: коли обчислення призвело до арифметичного переповнення, число занадто велике для подання у двійковій системі (у цьому випадку більше ніж 8 біт). Переповнення існує тоді, коли ці два біти відрізняються один від одного. Як уже згадувалося, знак кодується в старшому біті результату.
Іншими словами, коли обидва старші біти рядка перенесення 1 або 0, обчислення дало правильний результат, але коли вони утворюють комбінацію «10» або «01», трапилося знакове переповнення. Зручно те, що операція XOR, виконана над цими двома бітами, показує чи була операція виконана коректно. Як приклад, розглянемо 4-бітове додавання 7 та 3:
0111 (перенесення) 0111 (7) + 0011 (3) ============= 1010 (−6) некоректно!
Таким чином, два найстарших біти рядка перенесення утворюють комбінацію «01», що позначає арифметичне переповнення. Справді, 10102 = 1010, що знаходиться за межами 4-бітових чисел −8 та 7.
Загалом, будь-які N-бітові числа можуть бути додані без переповнення, якщо перед цим їх перевести до N + 1 бітового вигляду і після цього додати. Межі N + 1 бітових чисел більш ніж вдвічі перевищують межі N-бітових чисел, тож у новій системі переповнення ніколи не виникне.
Реалізація алгоритму перетворення в доповнювальний код (для 8-бітних чисел)
Pascal
if a<0 then a:=((not a) or 128) + 1;
C/C++
int8_t convert(int8_t a) { return ~a + 1; }
Переваги та недоліки
Переваги
- Комірка пам'яті може містити як n-бітні додатні числа, так і (n−1)-бітні числа зі знаком, причому операції додавання, віднімання і зсуву вліво однакові для обох форматів.
- Відсутність числа «-0». У оберненому коді таке число є.
Недоліки
- Стосовно складних форматів (таких, як рухома кома або двійково-десятковий код) переваги втрачаються.
- Модуль найбільшого числа не дорівнює модулю найменшого. Наприклад, для знакової цілої 8-бітової змінної найбільше число це 12710 = 7F16 = 011111112, а найменше: −12810 = 8016,доп. код = 100000002,доп. код. Відповідно, не для кожного числа можна записати протилежне. Операція зміни знаку може вимагати додаткової перевірки.
Приклад програмного перетворення
Якщо відбувається читання даних з файла або ділянки пам'яті, де вони зберігаються в двійковому доповняльному коді (наприклад, файл WAVE), може виявитися необхідним обернути байти. Якщо дані зберігаються в 8 бітах, необхідно, щоб значення 128—255 були від'ємними.
C# .NET / C style
byte b1 = 254; //11111110 (двійкове) byte b2 = 121; //01111001 (двійкове) byte c = 1<<(sizeof(byte)*8-1); //2 підноситься до 7 степеня. Результат: 10000000 (двійкове) byte b1Conversion=(c ^ b1) - c; //Результат: -2. А це, фактично, двійковий доповнювальний код. byte b2Conversion=(c ^ b2) - c; //Результат залишається 121, тому що знаковий розряд - нуль.
Див. також
Це незавершена стаття про програмування. Ви можете проєкту, виправивши або дописавши її. |
Ця стаття не містить . (листопад 2011) |
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Dopovnyalnij kod angl two s complement dopovnennya do 2 najposhirenishij sposib podannya vid yemnih chisel u komp yuterah Dozvolyaye zamist komandi vidnimannya vikoristovuvati komandu dodavannya dlya znakovih i bezznakovih chisel sho zmenshuye vimogi do arhitekturi komp yutera Dopovnyalnij kod vid yemnogo chisla mozhna otrimati tak invertuvati modul chisla u dvijkovomu viglyadi pershe dopovnennya i dodati odinicyu druge dopovnennya abo vidnyati chislo vid nulya Matematichno dopovnyalnij kod Xdop 2N 1 X de X chislo yake treba predstaviti u dopovnyalnomu kodi N k st rozryadiv chisla Najstarshij bit0 1 1 1 1 1 1 1 1270 1 1 1 1 1 1 0 1260 0 0 0 0 0 1 0 20 0 0 0 0 0 0 1 10 0 0 0 0 0 0 0 01 1 1 1 1 1 1 1 11 1 1 1 1 1 1 0 21 0 0 0 0 0 0 1 1271 0 0 0 0 0 0 0 128 Vosmirozryadni dopovnyalni kodiPodannya vid yemnogo chisla u dopovnyalnomu kodiPri zapisi chisla v dopovnyalnomu kodi starshij rozryad ye znakovim Yaksho jogo znachennya dorivnyuye 0 to v reshti rozryadiv zapisane dodatne dvijkove chislo sho zbigayetsya z pryamim kodom Dvijkove 8 rozryadne chislo zi znakom v dopovnyalnomu kodi mozhe predstavlyati bud yake cile v diapazoni vid 128 do 127 Yaksho starshij rozryad dorivnyuye nulyu to najbilshe cile chislo sho mozhe buti zapisane v ostannih 7 rozryadah dorivnyuye 27 1 displaystyle 2 7 1 sho dorivnyuye 127 Prikladi Desyatkove vidobrazhennya Dvijkove vidobrazhennya 8 bit pryamij obernenij dopovnyalnij127 01111111 01111111 01111111 1 00000001 00000001 00000001 0 00000000 00000000 00000000 0 10000000 11111111 1 10000001 11111110 11111111 2 10000010 11111101 11111110 3 10000011 11111100 11111101 4 10000100 11111011 11111100 5 10000101 11111010 11111011 6 10000110 11111001 11111010 7 10000111 11111000 11111001 8 10001000 11110111 11111000 9 10001001 11110110 11110111 10 10001010 11110101 11110110 11 10001011 11110100 11110101 127 11111111 10000000 10000001 128 10000000 Dopovnyalnij kod dlya desyatkovih chiselCe same mozhna vikoristovuvati i v komp yuternomu podanni desyatkovi chisla dlya kozhnogo rozryadu cifra X zaminyuyetsya na 9 X i do oderzhanogo chisla dodayetsya 1 Napriklad pri vikoristanni chotiriznachnih chisel 0081 zaminyuyetsya na 9919 9919 0081 0000 p yatij rozryad vikidayetsya Pri zastosuvanni tiyeyi zh ideyi do zvichnoyi 10 kovoyi sistemi chislennya vijde napriklad dlya gipotetichnogo procesora sho vikoristovuye 10 tkovu sistemu chislennya 10 kova sistema chislennya prostij zapis 10 kova sistema chislennya dopovnyalnij kod 13 001312 001211 001110 00109 00098 0008 2 00021 00010 0000 1 9999 2 9998 3 9997 4 9996 9 9991 10 9990 11 9989 12 9988 Peretvorennya u dopovnyalnij kodPeretvorennya chisla z pryamogo kodu v dopovnyalnij zdijsnyuyetsya za takim algoritmom Yaksho chislo zapisane v pryamomu kodi dodatne to do nogo dopisuyetsya starshij znakovij rozryad rivnij 0 i na comu peretvorennya zakinchuyetsya Yaksho chislo zapisane v pryamomu kodi vid yemne to vsi rozryadi chisla krim znakovogo invertuyutsya a do rezultatu dodayetsya 1 Do otrimanogo chisla dopisuyetsya starshij znakovij rozryad rivnij 1 Priklad Peretvorimo vid yemne chislo 5 zapisane v pryamomu kodi v dopovnyalnij Pryamij kod chisla 5 vzyatogo za modulem 101 Invertuyemo vsi rozryadi chisla otrimuyuchi takim chinom obernenij kod 010 Dodamo do rezultatu 1 011 Dopishemo zliva znakovij odinichnij rozryad 1011 Dlya zvorotnogo peretvorennya vikoristovuyetsya toj zhe algoritm A same 1011 Invertuyemo vsi rozryadi chisla otrimuyuchi takim chinom obernenij kod 0100 Dodamo do rezultatu 1 0101 I perevirimo dodavshi do dopovnyalnogo kodu 0101 1011 10000 p yatij rozryad vikidayetsya R adichni chislaV sistemi p adichnih chisel zmina znaku chisla zdijsnyuyetsya peretvorennyam chisla v jogo dopovnyalnij kod Napriklad yaksho vikoristovuyetsya 5 kova sistema chislennya to chislo protilezhne 1000 1 tak samo ye 4444 1 Arifmetichni operaciyiDodavannya Dodavannya dvoh chisel u dopovnyalnomu kodi ne potrebuye dodatkovih dij yaksho dodanki mayut protilezhni znaki u takomu vipadku znak sumi viznachayetsya avtomatichno Priklad dodavannya 15 ta 5 11111 111 perenesennya 0000 1111 15 1111 1011 5 0000 1010 10 Cej proces zalezhit vid obmezhennya vismoma bitami perenesennya do vidsutnogo dev yatogo najstarshogo bitu ignoruyetsya sho povertaye nam pravilnij rezultat 1010 Najstarshi dva biti ryadka perenesenih cifr mistyat vazhlivu informaciyu koli obchislennya prizvelo do arifmetichnogo perepovnennya chislo zanadto velike dlya podannya u dvijkovij sistemi u comu vipadku bilshe nizh 8 bit Perepovnennya isnuye todi koli ci dva biti vidriznyayutsya odin vid odnogo Yak uzhe zgaduvalosya znak koduyetsya v starshomu biti rezultatu Inshimi slovami koli obidva starshi biti ryadka perenesennya 1 abo 0 obchislennya dalo pravilnij rezultat ale koli voni utvoryuyut kombinaciyu 10 abo 01 trapilosya znakove perepovnennya Zruchno te sho operaciya XOR vikonana nad cimi dvoma bitami pokazuye chi bula operaciya vikonana korektno Yak priklad rozglyanemo 4 bitove dodavannya 7 ta 3 0111 perenesennya 0111 7 0011 3 1010 6 nekorektno Takim chinom dva najstarshih biti ryadka perenesennya utvoryuyut kombinaciyu 01 sho poznachaye arifmetichne perepovnennya Spravdi 10102 1010 sho znahoditsya za mezhami 4 bitovih chisel 8 ta 7 Zagalom bud yaki N bitovi chisla mozhut buti dodani bez perepovnennya yaksho pered cim yih perevesti do N 1 bitovogo viglyadu i pislya cogo dodati Mezhi N 1 bitovih chisel bilsh nizh vdvichi perevishuyut mezhi N bitovih chisel tozh u novij sistemi perepovnennya nikoli ne vinikne Realizaciya algoritmu peretvorennya v dopovnyuvalnij kod dlya 8 bitnih chisel Pascal if a lt 0 then a not a or 128 1 C C int8 t convert int8 t a return a 1 Perevagi ta nedolikiPerevagi Komirka pam yati mozhe mistiti yak n bitni dodatni chisla tak i n 1 bitni chisla zi znakom prichomu operaciyi dodavannya vidnimannya i zsuvu vlivo odnakovi dlya oboh formativ Vidsutnist chisla 0 U obernenomu kodi take chislo ye Nedoliki Stosovno skladnih formativ takih yak ruhoma koma abo dvijkovo desyatkovij kod perevagi vtrachayutsya Modul najbilshogo chisla ne dorivnyuye modulyu najmenshogo Napriklad dlya znakovoyi ciloyi 8 bitovoyi zminnoyi najbilshe chislo ce 12710 7F16 011111112 a najmenshe 12810 8016 dop kod 100000002 dop kod Vidpovidno ne dlya kozhnogo chisla mozhna zapisati protilezhne Operaciya zmini znaku mozhe vimagati dodatkovoyi perevirki Priklad programnogo peretvorennyaYaksho vidbuvayetsya chitannya danih z fajla abo dilyanki pam yati de voni zberigayutsya v dvijkovomu dopovnyalnomu kodi napriklad fajl WAVE mozhe viyavitisya neobhidnim obernuti bajti Yaksho dani zberigayutsya v 8 bitah neobhidno shob znachennya 128 255 buli vid yemnimi C NET C style byte b1 254 11111110 dvijkove byte b2 121 01111001 dvijkove byte c 1 lt lt sizeof byte 8 1 2 pidnositsya do 7 stepenya Rezultat 10000000 dvijkove byte b1Conversion c b1 c Rezultat 2 A ce faktichno dvijkovij dopovnyuvalnij kod byte b2Conversion c b2 c Rezultat zalishayetsya 121 tomu sho znakovij rozryad nul Div takozhPryamij kod Obernenij kod Cilochiselnij tip Algoritm Buta Ce nezavershena stattya pro programuvannya Vi mozhete dopomogti proyektu vipravivshi abo dopisavshi yiyi Cya stattya ne mistit posilan na dzherela Vi mozhete dopomogti polipshiti cyu stattyu dodavshi posilannya na nadijni avtoritetni dzherela Material bez dzherel mozhe buti piddano sumnivu ta vilucheno listopad 2011