خطای نهان در محاسبات با double و float !


در این پست به سوال مهم زیر می پردازیم:

" آیا نوع داده ی double و float برای عملیات ریاضی مناسب هستند؟ "

🔶پاسخ کوتاه اینه که در انجام عملیات ریاضی این دو نوع متغیر دقیق عمل نمی کنند و بعضی اوقات حاصل بسیار نزدیک به جواب اصلی است اما دقیقا همان نیست.

🔸این دو نوع متغیر نباید برای مقادیر مالی وهرآنچیزی که دقتش اهمیت دارد استفاده شود.

و برای مواردی که مقدار نیاز است دقیق باشد، باید از متغیر BigDecimal در جاوا استفاده کرد.

🔹اما باید در نظر داشت که BigDecimal بسیار کند تر عمل می کند! و اگر دقت خیلی مورد اهمیت نیست بهتر است از double یا float استفاده کرد و در نهایت اعداد را گرد کرد.

🔵 اما اگر مایلید علت را بدانید بقیه ی متن رو مطالعه کنید.

🔶 فرض کنید دو متغیر از جنس float یا double تعریف کنید و مقدار یکی را 2.1 و اون یکی رو 3.3 بگذارید. مجموع دو متغیر را چاپ کنید.چه میبینید؟

🔹بر خلاف انتظار نتیجه 5.4 نیست! نتیجه 5.3999996 است.(می توانید امتحان کنید!)

این بار مقدار هر دو را 2.5 بگذارید. مجموع را چاپ کنید. نتیجه 5.0 است!

🔸این قضیه در سایر عملیات های ریاضی هم برای float و double پیش میاد. تا اینجا فهمیدیم که این دو نوع متغیر در جاوا نتیجه ی دقیقی به ما نمیدن!

🔶اما ، واقعا چرا؟🤔

🔹قاعدتا کسانی که رشته شون کامپیوتر هست باید این رو بهتر بدونن و البته اینجا من فقط به کلیت موضوع
اشاره میکنم و در آخر چندتا رفرنس برای اطلاعات بیشتر معرفی می کنم.

📌اول به این دو تعریف یه نگاه بندازید:

💡 عدد ممیز شناور(float point number) چیست؟

💎 “اعداد ممیز شناور برای نمایش کمیت هایی استفاده می شوند که توسط اعداد صحیح قابل نمایش نیستند؛ چون یا آن ها دارای مقادیر کسری هستند یا این که خارج از محدوده قابل نمایش از نظر اندازه ی پهنای بیتی سیستم قرار دارند.”

💡استاندارد IEEE754 چیست؟

💎 در سال 1985 استاندارد 754 IEEE مطرح شد

اين استاندارد واگرايي شيوه هاي به كار رفته براي نمايش مميز

شناور را كاهش داد.

بدين ترتيب برنامه هاي نوشته شده براي مقاصد علمي قابل حمل شدند.

بسیاری از واحدهای ممیز شناور اکنون از استاندارد IEEE (بخوانید آی‌تریپل‌ئی) استفاده می‌کنند..

🔶 خب پس از دانستن این دو تعریف باید بگیم که ،‌در علوم کامپیوتر اعداد صحیح را خیلی ساده میتونیم به باینری تبدیل کنیم. اما برای اعداد اعشاری چالش بزرگی پیش رو هست تا علاوه بر قابل فهم بودن باینری شده ی اعداد اعشاری برای کامپیوتر ، دامنه ی خوبی از اعداد رو هم شامل بشن ، دقتشون بالا باشه و سرعت پردازششون خوب باشه تا سریع بشه باهاشون کار کرد و...

🔸 اولین بار که دانشمندان علوم کامپیوتر با این چالش رو به رو شدند راه های مختلفی برای پردازنده های مختلفی ارایه می کنند که هر کدومش دقت خاص خودش رو داشته.

🔶 در نهایت اتفاقی که میافته اینه که IEEE میاد و یک استانداردی رو با الگو گیری از نماد علمی اعداد ارایه می کنه به نام STD IEEE754.( که std همون standard هست)

❇️ اما علت روی دادن این خطا چیست؟ به طور کلی وقتی یک محاسبه مقداری را ایجاد می کند که نمی تواند دقیقا به وسیله ی قالب ممیز شناور ارایه شده توسط IEEE نمایش داده شود، سخت افزار باید نتیجه را به مقداری که به درستی نمایش داده می شود، گرد کند!

در استاندارد IEEE 754، روش پیش فرض برای این کار این است که به نزدیک ترین عدد گرد شود.

🔶امروزه همه کامپیوترهای مدرن از نمایش ممیز شناور که در استاندارد IEEE 754 مشخص شده برای تمامی اعدادی که با یک مانتیس و یک توان نمایش داده می شوند، بهره می‌برند.

🔶اگر دوست دارید که بیشتر درمورد IEEE 754 بدونید لینک های فوق العاده ی زیر رو از دست ندید:

📎 yon.ir/Yfcx4

📎 yon.ir/oQx0p

📎 yon.ir/bKVim

📎 yon.ir/X6oR4

📎 yon.ir/ZsF14

📎 yon.ir/UfABs