خب کلیتی از یکسری مسایل دیگه که در ارتباط با اعداد اعشاری ممیز شناور (Floating point) ممکنه رخ بدن:
کد:
(a + b) ×c ?= a×c + b×c
(a + b) + c ?= a + (b + c)
منظور از ?= در عبارات بالا این هست که در مواردی دو طرف میتونن مساوی نباشن! درحالیکه از نظر ریاضی دقیقا یکسان هستن و به گمانم هیچ برنامه نویسی هم انتظار نداره که مساوی نباشن. اما این امکان وجود داره. اینکه رخ میده یا نه، ظاهرا بستگی به عوامل مختلفی داره که شاید جز آزمون و احتیاط و زیرنظر گرفتن دقیق راه ساده ای برای جلوگیری از خطاهای پیش آمده در برنامه از این طریق نباشه؛ مگر اینکه دقیقا خصوصیات سخت افزار و نرم افزار (شامل کامپایلر) و مشخصات و پارامترهای عملیات انجام شده رو بدونید و با ساختار اعداد ممیز شناور و آنالیز ریاضی لازمه کاملا آشنا باشید.
مورد بعدی اینه که تفریق اعدادی که خیلی نزدیک بهم هستن میتونه به کاهش شدید دقت عملیات منجر بشه (یعنی خطا از تقریب طبیعی اعداد ممیز شناور هم خیلی فراتر بره). به این رخداد Cancellation گفته میشه.
عملیات مقایسه برای تساوی بین نتایج حاصل از دو عملیات ممیز شناور که از نظر ریاضی معادل هستن ممکنه خطا کنه، چون بسته به نوع عملیات و ترتیب عملوندها و پارامترهای دیگر، نتیجه براحتی میتونه تفاوت داشته باشه (توجه کنید که حتی یک اختلاف جزیی در عملیات مقایسه برای تساوی منجر به تفاوت نتیجهء مقایسه میشه).
باید متوجه عملیات Type cast هم بود چون در بعضی موارد ممکنه نتایج غیرمعمول بده. بعنوان مثال:
کد:
printf("%d\n", (int)((float)63.0/(float)9.0));// result: 7
printf("%d\n", (int)((float)0.63/(float)0.09));// result: 6
این خطا به این علت پیش میاد که عملیات Type cast معمولا گرد نمیکنه و بجاش بخش اعشاری رو کاملا نادیده میگیره. همچنین در کار با توابعی مثل Floor و ceil اینطور خطا میتونه پیش بیاد.
خب برای تعدادی از این محدودیت ها یا خطاها راهکارهای نرم افزاری خاصی ارایه شده. اما تقریبا هیچکدام کلی و صددرصد امن نیستن، ولی بهرحال میتونن پاسخگوی بعضی از نیازهای معمول باشن؛ بخصوص در برنامه هایی که نوع و محدودهء داده های اونها نسبتا محدود و معین و قابل پیش بینی هست. برای جستجو و مطالعهء این راهکارها به منبع ارایه شده برای این محتویات مراجعه کنید.
منبع: http://en.wikipedia.org/wiki/Floating_p ... y_problems |