رد شدن به محتوای اصلی

در استفاده از اعداد اعشاری در MATLAB دقت کنید

اگه جزء افرادی هستین که با نرم‌افزار MATLAB سر و کار دارین، حتما این مطلب رو بخونین تا به مشکلی که حدود یک ماه وقت من رو الکی گرفت بر نخورین.
یک ماهی بود که من از برنامه‌ای که نوشته بودم جواب دلخواهم رو نمی‌گرفتم.
تو برنامه متغیری بود که مقدارش به صورت اعشاری زیاد می‌شد و بعد با عدد ۱ مقایسه می‌شد که اگر مقدارش ۱ شده باشه یک سری دستورات اجرا بشه. ولی اون دستورات هیچ‌وقت اجرا نمی‌شدن و چون برنامه حجمش کمی زیاد بود، پیدا کردن این که مشکل از اجرا نشدن این قسمته تا وقتی که برنامه رو کاملا دقیق دیباگ نکردم معلوم نشد.

قضیه از این قراره که اعداد اعشاری و صحیح برای MATLAB متفاوت هستن.
در واقع جواب کد زیر در MATLAB برابر یک نخواهد شد و مقدار صفر رو برمی‌گردونه:
(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1) == 1
دلیلش هم اینه که MATLAB جواب اون جمع رو به صورت یک عدد اعشاری می‌شناسه (1.0000) و این عدد اعشاری نسبت به عدد صحیح ۱، یک بیت اضافه داره و در نتیجه این دو مقدار برای MATLAB برابر نخواهند بود.
راه حل این مشکل استفاده از کدی مانند کد زیر است:
(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1) - 1 <= eps
این یعنی اگر اختلاف عدد حاصل از عدد ۱ خیلی کم و در حد اپسیلن باشه، مقدار درستی (یعنی ۱) برگردونده بشه.
حالا نکته‌ی جالب این‌جاست که نمی‌شه پیش‌بینی کرد (یا حداقل من قانونشو نمی‌دونم) که MATLAB چه موقع مقادیر رو به صورت صحیح و چه موقع به صورت اعشاری در میاره. کد زیر:
(0.5 + 0.5) == 1
بر خلاف اولین کد مقدار درستی رو برمی‌گردونه چون MATLAB مقدار به دست اومده رو به عدد صحیح ۱ و نه به صورت اعشار تبدیل می‌کنه.
پس برای این‌که تو برنامه‌هاتون به مشکلات بیهوده برخورد نکنین و وقتتون گرفته نشه لطفا در استفاده از اعداد اعشاری و صحیح خیلی دقیق باشید.

نظرات

  1. منم دیروز با این مشکل مواجه شدم ... زود پیدا کردم مشکل رو .. امروز هم برا حلش سرچ کردم مطلب شما رو دیدم... ممنون .. آیا راهی وجود نداره که 1 رو به صورت اعشاری در بیاریم؟ یعنی 1 رو تبدیل کنیم به 1.0000؟

    پاسخحذف
  2. سلام.
    خوشحالم که این مطلب واستون مفید بوده.
    لطفا نگاهی به پست بعدی هم بیاندازید:
    http://flight-to-infinity.blogspot.com/2011/08/blog-post_10.html
    و مقاله ی ذکر شده در اون پست رو بخونید.
    در واقع مساله این نیست که عددی رو خود به خود به صورت اعشاری بشناسه. مساله اعدادی هستن که معادل دودویی دقیقی در سیستم ذخیره ی کامپیوتر ندارن و در نتیجه یک عدد نزدیک به اون ها با دقت بالا در نظر گرفته می شه (که به سادگی نمی شه فهمید عدد بعدیه یا قبلی). در نتیجه ممکنه در محاسبه این اعداد باعث ایجاد تفاوت در جواب بشن. اگر اون مقاله رو بخونین همه ی این ها رو توضیح داده.

    پاسخحذف

ارسال یک نظر

پست‌های معروف از این وبلاگ

فانوس

در ظلمت شب‌های بیابان هر بار از دور نور فانوسی را می‌بینم. به امید یافتن همراه به سمت نور می‌روم، اما هیچ هم‌مسیری نمی‌یابم. تنها دمی با فانوس‌به‌دستان هم‌صحبت می‌شوم. آن‌ها که خوبند پس از جدایی تکه‌ای از قلب مرا با خود می‌برند و ظالمان خاری در بدنم فرو می‌کنند. تو چه دانی که اولی دردناک‌تر است؟ در ظلمت بیابان قلبم تکه تکه و تنم پر از خار شده است. کاش فانوسی داشتم.

چهارمین برگ از دفترم

امروز چهارمین برگ از این دفتر هم ورق خورد. چهار سال... و هنوز هم این شعر مریم حیدرزاده، با صدای زنده‌یاد ناصر عبداللهی همدم لحظه‌های تنهایی من است: پشت این پنجره ها وقتی بارون میباره وقتی آهسته غروب تو خونه پا میذاره وقتی هر لحظه نسیم توی باغچه ها میاد توی خاک گلدونا بذر حسرت میکاره وقتی شبنم میشینه رو غبار جاده ها وقتی هر خاطره ای تورو یادم میاره وقتی توی آینه خودمو گم میکنم میدونم که لحظه هام رنگ آبی نداره تازه احساس میکنم که چشام بارونیه پشت این پنجره ها داره بارون میباره تازه احساس میکنم که چشام بارونیه پشت این پنجره ها داره بارون میباره

صخره‌نورد خسته

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