آیا اکسل باز دارید؟این را در A1 قرار دهید:
چی به دست آوردی؟اگر صفر گرفتید ، سعی کنید از اکسل بخواهید که رقم های بیشتری را از نقطه اعشاری به شما نشان دهد. با این حال ، به طور کلی ، اکسل به عنوان پیش فرض به نماد نقطه شناور زیر برمی گردد:
مطمئناً ، این کوچک است ، اما صفر نیست.
به طور جداگانه ، اگر صفحه گسترده من را از شماره ژانویه 2014 Compact بررسی کنید ، همراه با مقاله با عنوان "تغییرات در تقریب - اکتشافی در محاسبه" ، خواهید دید که در برخی از زبانه ها ، جمع تجمعی احتمالات برای دوتایی تقریبیتوزیع کمتر از 1 است (در حدود 10^-14). این ممکن است برای برخی از برنامه های توزیع ما مشکل ایجاد کند. اگر ما از حسابی و مداد و کاغذ استفاده می کردیم ، تعداد محاسبه شده باید به یک ، حداقل برای زبانه ها که از تقریب استفاده نمی کنند اضافه کنند. اما در اکسل نخواهد بود.
گرچه نمونه های من در بالا با اکسل سروکار دارد ، اما این منحصر به فرد برای اکسل نیست. جنبه هایی وجود دارد که چگونه اکسل به طور خاص نقطه شناور را کنترل می کند ، اما من می خواهم با مشکلات کلی شروع کنم و به جزئیات فریبنده نروم. فقط جزئیات آزار دهنده.
اول ، نمایش نقطه شناور از یک عدد واقعی چیست؟به نظر می رسد این:
(+/-) معنی دار* نماینده پایه
فرم های استاندارد معمولاً مجبور می شوند قسمت "معنی دار" بین 0. 0 تا 9. 999999 (به سطح دقت دستگاه) باشد. پایه مشخص خواهد شد (معمولاً دو برای رایانه). هر سیستم در مورد تعداد رقم قابل توجه (به نام دقت) محدودیت هایی خواهد داشت و محدودیت هایی برای نماینده (مثبت و منفی) وجود خواهد داشت. ممکن است بین اعداد مثبت و منفی عدم تقارن وجود داشته باشد تا کمترین تعداد منفی در مقدار مطلق با بزرگترین تعداد مثبت در سیستم برابر نباشد (به طور مشابه برای دامنه نمایندگان).
برای اغراق در اثر عملیات حسابی در نقطه شناور ، من از برخی از محدودیت های نسبتاً کم استفاده می کنم. من به چهار رقم مهم اجازه می دهم (9999 تا 9. 999 را نگه می دارد) ، به من اجازه می دهم که از سه تا چهار منفی استفاده کنم و از پایه 10 برای سهولت در بررسی عملیات استفاده می کنم.
بیایید برخی از مشکلات ناشی از حسابهای نقطه شناور را بررسی کنیم:
- سرریز
- زیر جریان
- از دست دادن دقت در تبدیل به نقطه شناور
- اضافه کردن تعداد بزرگی بسیار متفاوت
- تعداد زیادی از بزرگی های مشابه
- ضرب و تقسیم
سرریز سرریز هنگامی رخ می دهد که شماره ای که می خواهید در نقطه شناور بیان کنید از نظر بزرگی بسیار زیاد است.
برای مثال ساده ما ، بزرگترین شماره مجاز 9. 999*10^4 یا 99،990 است. از آنجا که اعداد به طور کلی به نزدیکترین تعداد دارای رقم های قابل توجه مجاز هستند ، این بدان معنی است که تعداد ما باید به 10. 0* 10^4 دور شود تا یک عدد در این سیستم سرریز شود.
گرد و دور زدن سرریز با سیستم متفاوت است. به طور کلی ، سرریز به عنوان بی نهایت یا نان بازگردانده می شود (یعنی یک عدد). اگر در جهت منفی سرریز شوید (داشتن یک عدد زی ر-9. 999 * 10^4 ، یعنی) ، ممکن است یک خطای مشابه را برگرداند یا ممکن است نتیجه امضا شود ، مانند infinity. هنگامی که اکسل سرریز می شود ، به طور کلی خطای #NUM را ایجاد می کند.
به طور کلی ، هنگامی که سرریز رخ می دهد ، نوعی خطا پرتاب می شود. این برخلاف نوع بعدی مشکل است.
جریان زیر آب هنگامی اتفاق می افتد که شماره ای که می خواهید بیان کنید از نظر بزرگی بسیار کوچک است.
در مثال ساده ما ، کوچکترین عدد مثبت بیان شده 0. 001 * 10^-3 یا 10^-6 است. شماره 10^-7 در این سیستم تحت تأثیر قرار می گیرد.
(من می خواهم توجه داشته باشم که Underflow تعریف واقعاً مهیج دارد ، و من مسئله را برای این خواندن ساده می کنم. اگر می خواهید جزئیات کامل داشته باشید ، منابع را در انتهای مقاله مشاهده کنید.)
Underflow همانطور که من آن را توصیف می کنم معمولاً به عنوان صفر برطرف می شود ، و به شما هشدار داده نمی شود که این اتفاق افتاده باشد. جریان برای بسیاری از نمونه های احتمال دوتایی من در "تغییرات در تقریب" رخ داده است که احتمال کوچکتر از 10^-308 (تقریباً) بود ، هرچند که گاهی اوقات هنگام محاسبه توابع صفر را برای اعداد بزرگتر باز می گرداند. حد 10^-308 در اکسل از محاسبه نقطه شناور با دقت مضاعف ناشی می شود ، و بسیاری از عملکردهای بومی در مناطق محدود هستند و در 10^-16 تحت فشار قرار می گیرند.
از دست دادن دقت در تبدیل به نقطه شناور ، اجازه دهید شماره 1/3 را به سیستم نقطه شناور خود تبدیل کنیم. اعشاری در حال تکرار است: 0. 333333. و با توجه به محدودیت های ما ، ما 1/3 را به عنوان 3. 333 * 10^-1 نشان می دهیم.
چقدر از ارزش واقعی آن فاصله دارد؟
این تفاوت 0. 0000333333 خواهد بود. یا 1/3 * 10^-4.
ما این از دست دادن دقت را همیشه در محاسبات خود می گیریم ، زیرا تعداد ما از اعشاری به نقطه شناور باینری تبدیل می شود. بسیاری از مواردی که در اعشاری خوب به نظر می رسند ، مانند 0. 1 یا 0. 4 ، در حال تکرار اعشار در باینری هستند. در باینری ، 0. 5 دارای نمای دوست داشتنی است: 0. 1. بنابراین ، هنگامی که 0. 1 و 0. 4 را به باینری تبدیل می کنیم و از این طریق دقت را از دست می دهیم ، و سپس سعی می کنیم این موارد را از 0. 5 کم کنیم ، 0 نمی گیریم.
یک راه خوب برای فکر کردن در مورد آن از نظر ارقام قابل توجه است ، و این که این سیستم سقف را به تعداد سیگفیگ هایی که مجاز به آن هستید ، تحمیل می کند. این ایده ای را به شما می دهد که چگونه دقت در عملیات نقطه شناور از بین می رود.
اضافه کردن تعداد بزرگی بسیار متفاوت ، بنابراین اجازه دهید برخی از حسابهای واقعی را انجام دهیم ، و فرض کنید که تمام اعداد دقیقاً قبل از انجام عملیات نشان داده شده اند (لزوماً در تبدیل از اعشاری به باینری ، مانند بالا نیست).
چه اتفاقی می افتد که 7. 777*10^2 و 9. 555*10^-1 را اضافه کنیم؟یعنی ما در حال تلاش برای اضافه کردن 777. 7 به 0. 9555 هستیم.
در حسابی دقیق ، پاسخ 778. 6555 است. اما این به شکلی بسیار مهم برای سیستم نقطه شناور ما است. ما باید آن را به 778. 7 دور کنیم تا با سیستم خود هماهنگ باشد. تفاوت بین پاسخ گرد و پاسخ دقیق ما 0. 0445 است. از نظر نسبی ، این یک خطای کوچک است ، بنابراین شاید این مسئله ما را آزار ندهد.
اما آنچه باید ما را آزار دهد این است که وقتی ما کاری مانند اضافه کردن یک دسته از اعداد را انجام می دهیم که در نهایت قرار است به یک جمع شود ، اما هر کدام بسیار کوچک هستند. این همان اتفاقی است که در انجام رابطه بازگشت برای احتمالات دوتایی برای ما اتفاق افتاده است. در بعضی مواقع ، ما در تلاش بودیم یک دسته از اعداد بسیار کم به چیزی که نزدیک به یک بود اضافه کنیم. بگذارید سعی کنیم 0. 010 * 10^-3 به 9. 999 * 10^-1 را اضافه کنیم. این به شرح زیر است: 0. 9999 + 0. 00001 = 0. 99991 = 0. 9999 در سیستم ما. اکنون فرض کنید ما سعی داشتیم این ستون از اعداد را اضافه کنیم:
. 9999 |
. 00001 |
. 00001 |
. 00001 |
. 00001 |
. 00001 |
. 00001 |
. 00001 |
. 00001 |
. 00001 |
. 00001 |
این باید برابر 1 باشد ، اما اگر این کار را به مرحله به مرحله انجام دهیم ، از بالا به پایین به صورت جفت ، هر 0. 010 * 10^-3 اضافی مانند اضافه کردن صفر به 0. 9999 است.
بنابراین چگونه این کار را انجام دهیم؟
به طور کلی ، شما با اضافه کردن کمترین تعداد با یکدیگر ، این نوع وضعیت را اداره می کنید. به طور کلی ، شما می خواهید تعداد مشابهی را با هم اضافه کنید.
در یک رویکرد ساده ، شما آن ستون اعداد را از پایین به بالا اضافه می کنید ، و سپس آنها را به 1 اضافه می کنند. توجه داشته باشید که علاوه بر این ، نقطه شناور مرتبط نیست. جالب نیست؟
یک رویکرد متفاوت، جمع کردن هر یک از این کوچکترین اعداد به صورت جفت و سپس افزودن آن جفت ها به یکدیگر است.
نکته 1: در صورت امکان، قبل از اینکه بخواهید به اعداد بزرگتر اضافه کنید، اعدادی با قدر کوچک مشابه را با هم اضافه کنید.
تفریق اعداد قدرهای مشابه مشکل در اینجا از دست دادن ارقام قابل توجه است. اگر 9. 999 و 9. 998 را کم کنید، 0. 001 یا 1. 000 * 10^-3 دریافت می کنید. شما با چهار رقم قابل توجه برای اعداد اولیه شروع می کنید و تنها با یک رقم مهم پایان می دهید.
این مسئله زمانی برجسته می شود که آن اعداد اصلی از خارج از سیستم ممیز شناور تبدیل شوند (همانطور که با تبدیل از اعشار به باینری اتفاق می افتد). بنابراین فرض کنید که اعداد اصلی در واقع 9. 999 و 9. 997571 بودند. تفاوت دقیق 0. 001429 یا 1. 429 * 10^-3 خواهد بود که در سیستم ممیز شناور ما قابل بیان است. این مقدار کمی با 1000 *10^-3 تفاوت دارد.
پس چه کنیم؟
قبل از اینکه اعداد را به سیستم خود تبدیل کنیم، 9. 997 را از هر دو کم می کنیم. این به ما 0. 002 = 2. 000 * 10^-3 و 0. 000571 = 0. 571 * 10^-3 می دهد.
نکته 2: قبل از تفریق اعداد ممیز شناور، ممکن است لازم باشد اعداد اصلی را "ماساژ" کنید یا الگوریتم خود را تغییر دهید تا ارقام قابل توجهی را در تفریق از دست ندهید.
پیوند ویکیپدیا را در منابع بررسی کنید تا نمونههایی از کاهش اهمیت را ببینید، به ویژه در فرمول درجه دوم وقتی b بزرگ و 4ac بسیار کوچک است.
ضرب و تقسیم مشکل ضرب و تقسیم مشکل سرریز و زیرریز است.
من برای اولین بار زمانی که برای یک استاد آمار مقداری کد فرترن را برای توزیع احتمالات نوشتم به این موضوع برخورد کردم. او میدانست که این اتفاق میافتد، و به من توصیه کرد که وقتی میخواهیم چیزی شبیه توزیع دوجملهای را برای مقادیر بسیار بزرگ n محاسبه کنم، سعی کنم اعداد را تا حد امکان نزدیک به یک ضرب و تقسیم کنم، تا از ریزش و سرریز جلوگیری کنم، واز دست دادن دقت که با نزدیک شدن به این محدودیت ها به وجود می آید.
با استفاده از سیستم ما، فرض کنید میخواهید انجام دهید:
(99990 * 19990 * 22220) / ( 11110 * 77770)
اگر این کار را در یک محاسبه کاملاً چپ به راست انجام دهیم، در اولین عملیات خود سرریز میشویم. اگر اینطور حساب کنیم:
1/77770 * 1/11110 * (99990 * 199990 * 22220)
ما در اولین ضرب از دو متقابل زیر آب می رویم.
کاری که می خواهید انجام دهید این است که مراحل را دوباره مرتب کنید (بیش از یک راه برای انجام این ترتیب برای جلوگیری از مشکلات وجود دارد):
(99990/77770) * (22220/11110) * 19990 = 1. 286 * 2. 000 * 19990 = 5. 141 * 10^4 (در سیستم ما)
نکته 3: برای جلوگیری از سرریز و زیرریزی (و همچنین از دست دادن دقت) هنگام ضرب و تقسیم اعداد، سعی کنید حاصلضرب را طوری تنظیم کنید که در اعداد نزدیک به یک ضرب شود.
یکی دیگر از مواردی که می توان امتحان کرد این است که محصولات را با استفاده از لگاریتم به جمع تبدیل کنیم. اجازه دهید وانمود کنیم که تابع لاگ ما (پایه 10) مشابه سیستم ممیز شناور ما عمل می کند.
سپس دریافت می کنیم: log(99990) + log(19990) + log(22220) – log(11110) – log(77770) = 4. 711
با افزایش قدرت، میگیریم: 10^4. 711 = 5. 140 * 10^4
بنابراین در این رویکرد دقت کمی را از دست میدهیم، اما انجام آن تبدیل ممکن است آسانتر از تلاش برای به هم زدن اصطلاحات در یک محاسبه باشد. من هر دوی این رویکردها را در مسئله تقریب دوجملهای با موفقیت متفاوت امتحان کردم.
نکته 4: گاهی اوقات تغییر محاسبات با اعمال یک تابع (مانند لگاریتم) می تواند خطر سرریز و زیرریز را از بین ببرد، اگرچه ممکن است منبع جدیدی برای از دست دادن دقت باشد.
برای بسیاری از محاسبات (اگر نه بیشتر) ، ما به انواع موقعیت هایی که باعث این مشکلات می شود نزدیک نشده ایم. با این حال ، همانطور که از ما خواسته می شود کارهای عددی پیچیده تری انجام دهیم ، این همان مسیری است که بسیاری از چارچوب های نظارتی و مدیریت ریسک در حال پیشروی هستند ، ممکن است ما به این موارد بپردازیم.
انواع مختلفی از هوشمندی که افراد برای تلاش برای جلوگیری از مشکلات محاسبه نقطه شناور استفاده کرده اند وجود دارد. منابع را برای برخی از اطلاعات دقیق تر در مورد انواع مشکلاتی که با عملیات نقطه شناور بوجود می آیند ، بررسی کنید.
منابع و منابع
مقالات قبلی توسط نویسنده
- "تغییرات در تقریب - اکتشافی در محاسبه" ، جمع و جور ، ژانویه 2014
- "آیا این قابل توجه است - با شماره های برقراری ارتباط و دقت جعلی" ، جمع و جور ، فوریه 2013
منابع خارجی
- "از دست دادن اهمیت ،" ویکی پدیا
- "نقطه شناور" ، ویکی پدیا ، IEEE STD 754-2008 ، پروفسور دبلیو کاهان ، اکتبر 1997
- "آنچه هر برنامه نویس باید درباره حسابی از نقطه شناور بداند"
- جان دی کوک ، اکتبر 2008 "پنج نکته برای برنامه نویسی نقطه شناور ،"
مری پت کمپبل ، FSA ، MAAA ، تحلیلگر زندگی برای Conning Research & Consulting است.