مقدمه
در بخش اول این سری آموزشی در رابطه با نحوه نمایش اعداد اعشاری ممیز ثابت علامت دار و بدون علامت و همچنین قوانین و چهارچوبهای لازم برای کار کردن با این اعداد توضیحاتی ارائه کردیم. در بخش دوم نیز مفهوم محاسبات با دقت محدود و مهمترین پارامترهایی را که ممکن است در محاسبات با دقت محدود مورد نیاز باشد، معرفی کردیم. در بخش سوم این سری قصد داریم قوانین محاسبات ممیز ثابت را بیان کنیم. این آخرین بخش از این سری آموزشی است و طبیعتاً کاربردیترین بخش نیز است. اگر علاقمند به تکمیل مهارتهای خود در محاسبات ممیز ثابت هستید، با این آموزش از پایگاه دانش هگزالینکس همراه شوید.
قوانین محاسبات ممیز ثابت
در ابتدا قرارداد میکنیم که اعداد ممیز ثابت را در حالت کلی به صورت (a,b)X نشان میدهیم، که میتواند یک عدد علامت دار مثل (a,b)Q و یا بدون علامت مثل (a,b)U باشد (یادآوری از بخش اول). به طور کلی عدد مقیاس دار با مقیاس b-2 در نظر گرفته میشود.
قوانین ۱ تا ۴
برخی از این قوانین پیشتر در بخشهای اول و دوم این سری آموزشی بیان شده است و فقط برای جمع بندی در اینجا باهم یکبار دیگر مرور میکنیم:
- طول بیت عدد بدون علامت (a,b)U برابر N=a+b است.
- طول بیت عدد علامت دار (a,b)Q برابر N=a+b+1 است.
- دامنه عدد بدون علامت (a,b)U عددی بین صفر تا 2a-2-b است.
- دامنه عدد علامت دار (a,b)Q عددی بین 2a– تا 2a-2-b است.
سایر قوانین به شرح زیر است.
قانون ۵: عملیات جمع
برای جمع دو عدد ممیز ثابت نقطه اعشاری یا مقیاس دو عدد باید یکسان باشد. به این معنی که برای جمع X(c,d)+Y(e,f) باید d=f و c=e باشد البته در مورد c=e توجه زیادی به آن نمیشود و بطور پیش فرض با اضافه کردن ‘0’ به MSB در اعداد بدون علامت و یا تکرار بیت علامت در اعداد علامت دار c , e را همسان میکنند.
قانون ۶: خروجی جمع
حاصل جمع دو عدد ممیز ثابت با مقیاس f همچون (e,f)X عددی ممیز ثابت با فرمت (e+1,f)X میشود بنابراین حاصل جمع دو عدد M بیتی عددی M+1 بیتی خواهد بود که معمولاً این بیت اضافه به نام بیت نقلی یا carry شناخته میشود.
قانون ۷: ضرب اعداد بدون علامت
در ضرب دو عدد با تعداد بیتهای معین، نتیجه حاصلضرب، برابر با مجموع تعداد بیتهای دو عدد شرکت کننده در ضرب خواهد بود. یعنی:
$$U(a_1,b_1) \times U(a_2,b_2) = U(a_1+ a_2,b_1+b_2)$$
دقت کنیم که در اینجا الزام به یکسان بودن فرمت ممیز ثابت دو عدد نداریم.
به عنوان مثال، فرض کنید قصد داریم دو عدد بدون علامت 16.25 و 0.75 را در هم ضرب کنیم. اگر برای نمایش هر دو عدد از ۸ بیت و به ترتیب از فرمت U(5,3) برای عدد اول و فرمت U(0,8) برای عدد دوم استفاده کنیم، عدد 16.25 برابر با 192 و عدد 0.75 برابر 130 میشود (اگر هنوز نمیدانید که چگونه این مقیاس بندی ار انجام دادیم به بخش اول این آموزش مراجعه کنید). در نهایت حاصلضرب این دو عدد برابر با 12.1875 خواهد بود که ۵ بیت صحیح و ۱۱ بیت اعشاری دارد. نحوه محاسبه این حاصلضرب به صورت زیر خواهد بود (دقت کنید که نقاط بین بیتها کاملاً فرضی هستند و صرفاً جهت شفاف شدن موضوع ارائه شدهاند):
$$10000.010 \times .11000000 = 01100.00110000000$$
قانون ۸: ضرب اعداد علامت دار
در ضرب اعداد علامت دار بازهم تعداد بیتهای حاصلضرب برابر مجموع تعداد بیتهای دو عدد ضرب شونده است با یک تفاوت بسیار کوچک. این تفاوت مربوط به بیت علامت است که نباید فراموش کنیم. از آنجایی که هر دو عدد علامت دار هستند و هر کدام یک بیت علامت دارند، نیازی به نمایش دو بیت علامت نداریم و تنها یکی از آنها کافی است. از بخش اول بیاد داریم که عدد (a,b)Q دارای a+b+1 بیت است. پس برای ضرب اعداد علامت دار داریم:
$$Q(a_1,b_1) \times Q(a_2,b_2) = Q(a_1+ a_2+1,b_1+b_2)$$
به عنوان مثال، فرض کنید قصد داریم اینبار دو عدد علامت دار 16.25 و 0.75 را در هم ضرب کنیم. اگر برای نمایش هر دو عدد از ۸ بیت و به ترتیب از فرمت Q(5,2) برای عدد اول و فرمت Q(0,7) برای عدد دوم استفاده کنیم، عدد 16.25 برابر با 96 و عدد 0.75 برابر 65 میشود (اگر هنوز نمیدانید که چگونه این مقیاس بندی را انجام دادیم به بخش اول این آموزش مراجعه کنید). در نهایت حاصلضرب این دو عدد برابر با 12.1875 خواهد بود که ۶ بیت صحیح و ۹ بیت اعشاری دارد، یعنی اینجا به جای ۱۶ بیت میتوانیم از ۱۵ بیت استفاده کنیم. نحوه محاسبه این حاصلضرب به صورت زیر خواهد بود (دقت کنید که نقاط بین بیتها کاملاً فرضی هستند و صرفاً جهت شفاف شدن موضوع ارائه شدهاند همینطور یکی از بیتهای علامت حذف شده است):
$$010000.01 \times 0.1100000 = 001100.001100000$$
قانون ۹: تقسیم اعداد بدون علامت
اگر فرض کنیم حاصل تقسیم دو عدد بدون علامت U(a1,b1) و U(a2,b2) به صورت U(a3,b3) است.
$$\frac{U(a_1,b_1)}{U(a_2,b_2)}=U(a_3,b_3)$$
آنگاه برای محاسبه مقادیر a3 و b3 در رابطه بالا بایستی به صورت زیر عمل کنیم.
$$\frac{2^{a_1}-2^{-b_1}}{2^{-b_2}}=2^{a_1+b_2}-2^{b_2-b_1}$$
پیش از اینکه وارد روابط ریاضی بشویم و کمی با نامعادلات بازی کنیم، لازم است به یک نکته مهم توجه کنیم. برای محاسبه فرمت حاصل تقسیم باید بخش صحیح و بخش اعشاری به صورت جداگانه محاسبه کنیم. برای محاسبه بخش صحیح لازم است بزرگترین حاصل تقسیم و برای محاسبه بخش اعشاری باید کوچکترین حاصل تقسیم را بدست بیاوریم.
در عمل ما برای بدست آوردن بزرگترین حاصل تقسیم ، بزرگترین مقسوم را بر کوچکترین مقسوم علیه تقسیم میکنیم. بزرگترین مقسوم (صورت کسر) حتماً دارای بخش صحیح و اعشاری است و کوچکترین مقسوم علیه (مخرج کسر) فقط دارای بخش اعشاری است.
بزرگترین حاصل = بزرگترین مقسوم بخش بر کوچکترین مقسوم علیه
بنابراین بزرگترین مقدار خارج قسمت باید بزرگتر یا مساوی مقدار محاسبه شده باشد یعنی باید یک نامساوی به صورت زیر حل کنیم:
$$2^{a_3}-2^{-b_3}\geq2^{a_1+b_2}-2^{b_2-b_1}$$
پس طبیعی است که یاید a3=a1+b2 در نظر گرفته شود. اما در مورد بخش اعشاری یا تعیین نقطه ممیز ثابت باید چند مورد در نظر گرفته شود. ابتدا نامعادلات زیر را در نظر بگیرد:
$$2^{a_3}-2^{-b_3}\geq2^{a_3}-2^{b_2-b_1} \\ -2^{-b_3}\geq-2^{b_2-b_1} \\ 2^{-b_3}\leq2^{b_2-b_1} \\ {-b_3}\leq{b_2-b_1} \\ {b_3}\geq{b_1-b_2}$$
پس تا اینجا اولین محدودیتی که باید اعمال شود را بدست آوردیم. به این ترتیب b3 باید از b1-b2 بزرگتر باشد. حال کوچکترین مقداری که از تقسیم حاصل میشود را در نظر میگیریم. کوچکترین مقسوم (صورت کسر) فقط دارای بخش اعشاری است و کوچکترین مقسوم علیه (مخرج کسر) حتماً دارای هر دو بخش بخش صحیح و اعشاری است.
کوچکترین حاصل = کوچکترین مقسوم بخش بر بزرگترین مقسوم علیه
$$\frac{2^{-b_1}}{ 2^{a_2}-2^{-b_2}}$$
در نتیجه b3 باید در نامعادله زیر صدق کند با کمی ساده سازی به راحتی در مییابیم که:
$$2^{-b_3}\leq\frac{2^{-b_1}}{ 2^{a_2}-2^{-b_2}} \\ \Rightarrow\:b_3 \geq b_1 +\log_{2} (2^{a_2}-2^{-b_2})$$
با مقایسه این محدودیت با محدودیت قبلی و با فرض مثبت بودن b2 نا معادله آخر سخت گیرانه تر از نامعادله b3 ≥ b1-b2 است.بنابراین از این نامعادله برای محاسبه بخش اعشاری استفاده میکنیم و این مقدار برای b3 قرار داده میشود.
$$b_3 \geq \log_{2} (2^{a_2+b_1}-2^{b_1-b_2})$$
در نتیجه فرمت ممیز ثابت حاصل تقسیم دو عدد ممیز ثابت بدون علامت به صورت زیر خواهد بود:
$$\frac{U(a_1,b_1)}{U(a_2,b_2)}=U(a_1+b_2, \log_{2} (2^{a_2+b_1}-2^{b_1-b_2}))$$
قانون ۱۰: تقسیم اعداد علامت دار
اگر فرض کنیم r= n/a است و n یک عدد اعشاری ممیز ثابت است که با فرمت Q(an,bn) مقیاس بندی شده و d عددی با فرمت Q(ad,bd) است. با این فرض فرمت ممیز ثابت عبارت n/d یعنی Q(ar,br) به چه شکل خواهد بود؟ مجدداً فرض میکنیم مقدار rmax از رابطه زیر محاسبه میشود.
$$|r_{max}|=\frac{|n_{max}|}{|d_{min}|}=\frac{2^{a_n}}{2^{-b_d}}=2^{a_n+b_d}$$
از آنجایی که ماکزیمم مقدار |r| یک عدد مثبت است. وقتی صورت و مخرج کسر هر دو اعدادی منفی باشند پسar=an+bd+1 است. از سوی دیگر مقدار rmin برابر است با
$$|r_{min}|=\frac{|n_{min}|}{|d_{max}|}=\frac{2^{-b_n}}{2^{a_d}}=2^{-(a_d+b_n)}$$
که در نتیجه br=ad+bn است، بنابراین:
$$\frac{Q(a_n,b_n)}{Q(a_d,b_d)}=Q(a_n+b_d+1, a_d+b_n)$$
قانون ۱۱: شیفت اعداد
شیفت در اعداد ممیز ثابت به دو صورت ممکن است: شیفت به صورت حقیقی، و شیفت به صورت مجازی. در ادامه هر یک از این دو شرح داده میشود و تأثیر در فرمت عدد اعشاری خروجی بیان میشود. در اینجا قرارداد میکنیم که شیفت n بیت به معنی شیفت به راست میباشد و شیفت به چپ به ازای مقادیر منفی n انجام میشود.
شیفت حقیقی
در واقع عمل شیفت حقیقی با جابجایی موقعیت بیتها در رجیستر نمایش دهنده عدد انجام میشود. شیفت به دو علت ممکن است انجام شود. ضرب یا تقسیم عدد به توانی از ۲ یا تغییر فرمت عدد اعشاری (تغییر مقیاس). در شیفت حقیقی به دلیل ضرب یا تقسیم به توانی از ۲ مکان بیتها جابجا میشود در هر دو حالت با فرض ثابت بودن تعداد بیتهای رجیستر، نتیجه شیفت کاهش صحت یا سرریز را به همراه دارد.
شیفت به دلیل ضرب یا تقسیم: در شیفت حقیقی به دلیل ضرب یا تقسیم به توانی از ۲ مکان بیتها جابجا میشود ولی حاصل خروجی دارای فرمتی همانند فرمت عدد قبل است.
$$X(a,b) >> n = X(a,b)$$
به عنوان مثال فرض کنید قصد داریم عدد بدون علامت 16.25 را که با فرمت U(5,3) در ۸ نمایش داده شده است در ۲ ضرب کنیم در این صورت خواهیم داشت:
$$U(5,3) (10000.010) >> 1 = U(5,3) (00000.100) = 0.5$$
انتظار داریم پاسخ ما برابر با 32.5 باشد، اما به دلیل بروز سرریز بیت با ارزش از دست رفته است و پاسخ حاصل نامعتبر است. مشابهاً اگر عدد 16.25 را بر ۴ تقسیم کنیم، خواهیم داشت:
$$U(5,3) (10000.010) >> -2 = U(5,3) (00100.000) = 4$$
همانطور که توجه شدید کمی از دقت محاسبات را از دست دادیم و به جای عدد 4.0625 پاسخ برابر با ۴ است. شیفت حقیقی اعداد علامت دار هم دقیقاً به همین شکل است. (دقت کنید که نقاط بین بیتها کاملاً فرضی هستند و صرفاً جهت شفاف شدن موضوع ارائه شدهاند) نکته حائز اهمیت در این بخش الزام به حفظ بیت علامت است. یعنی در صورت شیفت به راست و یا چپ ما اجازه حذف بیت علامت را نداریم و باید موقعیت آن را ثابت نگه داریم.
شیفت حقیقی به منظور اصلاح فرمت: در شیفت حقیقی به منظور اصلاح و تغییر فرمت ممیز ثابت، مکان بیتها به چپ یا راست تغییر میکند. در عمل این کار باعث تغییر مکان نقطه ممیز ثابت (نقطه اعشار) نیز میشود و در نتیجه تغییر فرمت خروجی را در پی خواهد داشت. به عنوان مثال که دو عدد فرضی ممیز ثابت را در نظر بگیرید که باید یکدیگر جمع بشوند. طبق قانون جمع یاد گرفتیم که تعداد بیتهای حاصل جمع دو عدد n بیتی برابر n+1 خواهد بود. برای حفظ دقت محاسبات در n بیت، ناگزیر باید عدد حاصل یک بیت به سمت راست شیفت داده شود و بیت LSB را در نظر نگیریم. در این حالت بعد از اعمال شیفت نقطه ممیز ثابت به اندازه یک بیت جابجا میشود.
به عنوان مثال، فرض کنید که قصد داریم دو عدد بدون علامت 15.875 و 16.25 را که هر دو با ۸ بیت و فرمت U(5,3) نمایش داده شده اند با هم جمع کنیم. در این صورت داریم:
$$10000.010+01111.111 = 100000.001 >> -1 = 100000.00$$
ملاحظه میکنید که با شیفت به راست و حذف بیت کم ارزش کمی از دقت محاسبات (مثل شیفت حقیقی) کاسته شده است، اما در عوض از سرریز حاصل جمع و غلط شدن پاسخ ممانعت به عمل آمده است. علاوه بر این فرمت پاسخ به U(6,2) تغییر یافته است.
در شیفت حقیقی باید در نظر داشته باشیم که در صورت ثابت نگه داشتن طول بیت خروجی همانند وروردی، عمل شیفت میتواند باعث از دست رفتن تعدادی از بیتها و در نتیجه کاهش صحت عدد بشود و یا باعث سر ریز بیتها در صورت شیفت به چپ شود.
شیفت مجازی
شیفت مجازی باعث جابجایی موقعیت بیتها نمیشود ولی موقعیت نقطه ممیز در بین آن ها جابجا میشود و به همین دلیل به آن مجازی گفته میشود زیرا در حقیقت نقطه ممیز ثابت در عدد نمایش داده شده در بیتها وجود ندارد و فقط قراردادی در ذهن طراح و برنامه نویس است. این شکل از شیفت یک جایگزین مناسب برای شیفت حاصل از ضرب یا تقسیم به توانی از ۲ است با این مزیت که دیگر مشکل از دست دادن برخی بیتها، کاهش دقت عدد و یا سرریز شدن آن را نداریم.
$$X(a,b) >> n = X(a-n,b+n)$$
من این نوع از شیفت را بیشتر از همه دوست دارم و عملاً بسیار پرکاربرد هم هست. در واقع بهترین راه برای محاسبه عملیات ضرب و تقسیم در توانهای صحیح ۲ همین روش است. به مثالهای زیر دقت کنید:
$$10000.010*2 = 100000.10 \\ 10000.010*4 = 1000001.0 \\ 10000.010*8 = 10000010.$$
$$10000.010/2 = 1000.0010 \\ 10000.010/4 = 100.00010 \\ 10000.010/8 = 10.000010$$
حتماً میتوانید به سادگی مقدار واقعی این اعداد را حدس بزنید (اینطور نیست؟) ما باز هم برای محاسبات از عدد بدون علامت 16.25 با فرمت U(5,3) کردیم. برای عدد علامت دار 16.25 با فرمت Q(5,2) نیز به صورت زیر عمل کنیم.
$$010000.01/2 = 01000.001 \\ 010000.01/4 = 0100.0001 \\ 010000.01/8 = 010.00001$$
قانون ۱۲: کاهش یا افزایش طول بیت
کاهش یا افزایش طول بیت یک عدد ممیز ثابت از طریق اضافه یا کم کردن بیتهای نمایش دهنده آن عدد انجام میشود. این کاهش یا افزایش بیت میتواند در بیتهای کم ارزش و یا در بیتهای پرارزش اتفاق بیافتد. اما بطور معمول کاهش طول بیت از بریدن و دور ریختن بیتهای کم ارزش انجام میشود. این دقیقاً همان تعریف ترانکیشن است. افزایش طول بیت با اضافه کردن صفر به بیتهای پر ارزش اعداد بدون علامت یا تکرار بیت MSB اعداد علامت دار صورت میگیرد.
با این حال افزایش طول بیتها میتواند به منظور افزایش تفکیک پذیری در نمایش عدد در بیتهای کم ارزش نیز انجام شود.
افزایش طول بیت نمایش یک عدد به n بیت با هدف ثابت نگهداشتن دقت تفکیک پذیری باعث تغییر فرمت بصورت زیر میشود. یعنی تعداد بیتهای صحیح از a بیت به n-b افزایش مییابد. پس در این حالت افزایش بیتهای پر ارزش را خواهیم داشت:
$$EXTHn(X(a,b)) = X(n-b,b)$$
در نقطه مقابل افزایش بیتهای نمایش دهنده به n بیت به منظور ارتقاء تفکیک پذیری عدد (افزایش بیتهای اعشاری)، تغییر فرمت زیر را به دنبال خواهد داشت.
$$EXTLn(X(a,b)) = X(a,n-a)$$
در این صورت افزایش بیتها، با اضافه کردن صفر به بخش کم ارزش (LSB) انجام میشود. واضح است که در اینجا n-a قطعاً بزرگتر از b خواهد بود.
کاهش طول بیت نیز میتواند با توجه به اینکه نیاز به حفظ بیتهای بخش صحیح و یا بخش اعشاری داریم، انجام شود. اگر کاهش بیت با هدف حفظ بخش صحیح انجام شود بیتهای کم ارزش (LSB) بریده و دور ریخته میشوند. که این کار کاهش تفکیک پذیری را در پی خواهد داشت.
$$TRNLn(X(a,b)) = X(a,n-a)$$
در صورتی که برای کاهش طول بیت بخش کم ارزش اهمیت بیشتری دارد و نیاز به حفظ آن هست. بیتهای پر ارزش حذف میشوند.
$$TRNHn(X(a,b)) = X(n-b,b)$$
لازم است به این نکته دقت کنید که اگر بخش صحیح عدد نمایش داده شده بزرگتر از مقدار قابل نمایش در n-b بیت باشد، سرریز رخ میدهد و مقدار متفاوتی نمایش داده میشود. پس در کاهش تعداد بیتهای صحیح با وسواس و دقت بیشتری عمل کنید!
نکته آخر اینکه، یک الگوی ثابت برای انتخاب بین پارامترهای ممیز ثابت وجود ندارد و در بسیاری از موارد یک مصالحه بین تفکیک پذیری و دامنه نمایش اعداد، برای افزایش یا کاهش طول بیت بصورت ترکیبی در نظر گرفته میشود.
جمع بندی
در این سری آموزشی تقریباً تمامی مفاهیم مورد نیاز کار با اعداد ممیز ثابت را به شما آموزش دادیم. طبیعی است که روابط ریاضی کمی بیش از حد پیچیده و خسته کننده به نظر میرسد، من هم با شما موافقم، به شما پیشنهاد میکنم وقت کمتری روی شیوه اثبات روابط بگذارید و بیشتر روی نتایج پایانی متمرکز شوید. فراموش نکنید که برای تسلط به روشها و قوانین مطرح شده شما نیاز دارید به تعداد کافی مثال حل کنید. در صورتی که سوألی در رابطه با این سری آموزشی داشتید، حتماً با ما در میان بگذارید.
نبع: digitalsignallabs
5 در مورد “اعداد اعشاری ممیز ثابت (بخش سوم: قوانین پایه محاسبات)”
از شما بسیار متشکرم…
برای روشن تر شدن مبحث شیفت …
لطفا یک مثال عددی هم از شیفت حقیقی و مجازی بزنید.
سلام و عرض ادب خدمت شما سهند عزیز،
مثالهایی به بخش شیفت (قانون ۱۱) در متن اضافه شد تا درک مفاهیم توضیح داده شده برای شما و سایر علاقمندان تسهیل شود. از همراهی شما سپاسگزاریم.
سلام و ممنون از توضیحات بسیار مفیدتون…
لطف میکنید از مبحث ضرب و تقسیم اعداد علامت دار هرکدام یک مثال بزنید.
سلام و درود فراوان بر شما دوست عزیز،
ممنون از وقتی که برای نوشتن این پیام گذاشتید.
با توجه به اینکه این درخواست شما خواسته دوستان دیگری هم بوده، مثالهایی برای بخش ضرب به متن اصلی اضافه شد. مثالهای مربوط به تقسیم هم در ادامه اضافه میشود.