اگر با C، سیستمپروگرمینگ، کامپایلر، اسمبلی یا حتی دیباگکردن باینری سروکار داشته باشید، دیر یا زود به یک سئوال اساسی میرسید:
عددهای منفی واقعاً چطور داخل حافظه ذخیره میشن؟
تقریباً روی همهی معماریهای مدرن، جواب two’s complementئه.
اما two’s complement فقط یک روش ذخیرهسازی نیست؛ یکی از مهمترین ترفندهای طراحی کامپیوتره که باعث میشه CPU بتونه جمع، تفریق، اعداد مثبت، اعداد منفی و overflow رو با یک منطق بسیار ساده مدیریت کنه.
———
مسئله از کجا شروع میشه؟
در باینری معمولی، اگر ۸ بیت داشته باشیم:
00000000 = 0
00000001 = 1
00000010 = 2
...
01111111 = 127
تا اینجا همهچیز روشنه. اما با ۸ بیت فقط ۲۵۶ الگوی مختلف داریم. حالا سئوال:
با همین ۲۵۶ الگو، هم عدد مثبت داشته باشیم، هم عدد منفی، چطور باید تقسیمشون کنیم؟
در سیستم two’s complement برای ۸ بیت، بازه اینه:
-128 تا +127
یعنی:
00000000 = 0
00000001 = 1
...
01111111 = 127
———
10000000 = -128
10000001 = -127
...
11111110 = -2
11111111 = -1
نکتهی مهم اینجاست: بیت سمت چپ فقط علامت نیست بلکه وزنش منفیئه.
bit: 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
weight: -128 | 64 | 32 | 16 | 8 | 4 | 2 | 1
پس مقدار این باینری:
11111111
میشه:
-128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = -1
برای همین
0xFF در signed 8-bit برابر -1 است.———
قانون اصلی two’s complement
برای پیدا کردن نمایش باینری
-x در N بیت:1. نمایش باینری x رو بنویس
2. همه بیتها رو invert کن
3. یک واحد اضافه کن
مثلاً برای
-5 در ۸ بیت:اول
+5:00000101
invert:
11111010
plus one:
11111011
پس:
-5 = 11111011
اگر مقدارش رو با وزن بیتها حساب کنیم:
11111011
= -128 + 64 + 32 + 16 + 8 + 0 + 2 + 1
= -5
در مهندسی نرمافزار، تفاوت آدمی که فقط کد مینویسه با آدمی که سیستم رو میفهمه، دقیقاً از همین سؤالهای ظاهراً ساده شروع میشه. توی پارت دوم به این روش بهطور عمیقتر میپردازیم.
Group: @azad_program
Channel: @kiau_program




