آموزش پایتون - اعداد اعشاری

هنگام کار با اعداد، با اعداد ممیز شناور مواجه می‌شویم. این‌ها اعدادی هستند که دارای نقطه اعشار هستند، مانند ۱.۱۲، ۱۲.۰۱ یا ۳۲۱.۲۴۳-. اعداد ممیز شناور به‌طور گسترده در محاسبات روزمره استفاده می‌شوند زیرا به ما امکان می‌دهند مقادیر بسیار بزرگ و بسیار کوچک را به روشی مناسب نشان دهیم.

با این حال، حساب ممیز شناور گاهی اوقات می‌تواند به گونه‌ای رفتار کند که هنگام مشاهده نتیجه باعث شگفتی شود. به عنوان مثال، ما انتظار عملیات ساده‌ای مانند 0.1+0.2= 0.3 را داریم، اما پایتون می‌گوید این مقدار 0.30000000000000004 است. این یک باگ در پایتون نیست، بلکه نتیجه نحوه نمایش اعداد اعشاری در داخل رایانه‌ها است.

حساب ممیز شناور

حساب ممیز شناور به محاسباتی اشاره دارد که شامل اعدادی با بخش‌های اعشاری است و معمولاً در قالبی بر اساس استاندارد IEEE 754 نشان داده می‌شود. یک عدد ممیز شناور در حافظه با استفاده از تعداد ثابتی از رقم‌های دو دویی (بیت‌ها) ذخیره می‌شود.

در پایتون، نوع پیش‌فرض ممیز شناور float نامیده می‌شود و از ۶۴ بیت استفاده می‌کند. این عدد به سه بخش تقسیم می‌شود:

  • بیت علامت − نشان می‌دهد که عدد مثبت است یا منفی.
  • نما (توان) − مقیاس عدد را به سمت بالا یا پایین نشان می‌دهد.
  • مانتیس (رقم‌های معنی‌دار) − رقم‌های عدد را ذخیره می‌کند.

این قالب به پایتون اجازه می‌دهد تا طیف وسیعی از مقادیر (از حدود 10^-308 تا 10^308) را نشان دهد و تغییرات بسیار کوچک بین آن‌ها را مدیریت کند.

مشکلات و محدودیت‌ها

بیایید درباره برخی از مشکلات اصلی حساب ممیز شناور بحث کنیم:

خطاهای دقت

از آنجایی که float از تعداد محدودی بیت استفاده می‌کند، نمی‌تواند هر عدد اعشاری را دقیقاً ذخیره کند، که منجر به خطاهای کوچک گرد کردن می‌شود.

print(0.1 + 0.2)   # Expected output: 0.3

خروجی برنامه بالا به صورت زیر است -

0.30000000000000004

در این حالت، نتیجه کمی نادرست است زیرا 0.1 و 0.2 نمایش باینری دقیق ندارند.

مشکلات مقایسه

به دلیل مشکلات دقت، مقایسه مستقیم اعداد ممیز شناور اغلب با شکست مواجه می‌شود.

a = 0.1 + 0.2
print(a == 0.3)

خروجی برنامه بالا به صورت زیر است -

False

از دست دادن ارقام معنی‌دار

در این سناریو، زمانی که دو عدد ممیز شناور تقریباً برابر را از هم کم می‌کنیم، تفاوت‌های کوچک می‌توانند بزرگ‌نمایی شوند و منجر به از دست رفتن ارقام معنی‌دار شوند.

a = 2.000001
b = 2.0000000
print(a - b)

خروجی برنامه بالا به صورت زیر است -

1.000000000139778e-06

سرریز و زيرریز

اعداد ممیز شناور دارای حداکثر و حداقل مقادیر قابل نمایش هستند. اگر محاسبه از این حدود فراتر رود:

  • سرریز (Overflow) − این عدد بسیار بزرگ است و منجر به بی‌نهایت می‌شود.
  • زیرریز (Underflow) − عدد بسیار نزدیک به صفر است و منجر به 0.0 می‌شود.
large = 1e3211
print(large * 10)  # Overflow
small = 1e-213
print(small / 10)  # Underflow

خروجی برنامه بالا به صورت زیر است -

inf
1e-214

مثال‌هایی از استفاده از حساب ممیز شناور

بیایید برخی از مثال‌ها را بررسی کنیم تا در مورد حساب ممیز شناور بیشتر بفهمیم.

مثال ۱

مثال زیر را در نظر بگیرید که در آن قصد داریم از تابع round() استفاده کنیم.

a = 0.1 + 0.2
print(a)
print(round(a, 2)) 

خروجی برنامه بالا به صورت زیر است -

0.30000000000000004
0.3

مثال ۲

در مثال زیر، قصد داریم از متد math.isclose() استفاده کنیم تا بررسی کنیم آیا دو عدد به اندازه کافی به هم نزدیک هستند یا خیر.

import math
a = 0.1 + 0.2
print(math.isclose(a, 0.3)

در ادامه خروجی برنامه بالا آمده است -

True

پیشرفت مطالعه: وضعیت خوانده‌شدن این درس فقط در همین مرورگر ذخیره می‌شود؛ بدون نیاز به حساب کاربری.