أحمد حايس
الرئيسيةمن أناالدوراتالمدونةسوق الأوامرالمناهج والباقاتالشركاء
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

المنصة مبنية على الوضوح، التطبيق، والنتيجة النافعة: شرح مرتب يساعدك تفهم الأدوات، تكتب كودًا أفضل، وتستخدم الذكاء الاصطناعي بوعي داخل العمل الحقيقي.

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • المناهج والباقات
  • سوق الأوامر
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالمناهجالمدونةالدخول
البرمجة بالعربي

ليه 0.1 + 0.2 ما بيساويش 0.3؟ الفاصلة العائمة من الصفر

مبتدئ10 يوليو 20264 دقائق قراءة
ليه 0.1 + 0.2 ما بيساويش 0.3؟ الفاصلة العائمة من الصفر

ليه 0.1 + 0.2 ما بيساويش 0.3؟ الفاصلة العائمة من الصفر

المستوى: مبتدئ. المقال ده متكتب لحد لسه بادئ في البرمجة. أي مفهوم صعب هتلاقيه متشروح بمثال بسيط الأول، وبعدين بالتعريف العلمي الدقيق.

بعد المقال ده هتعرف بالظبط ليه الكمبيوتر بيقولك 0.1 + 0.2 = 0.30000000000000004، إزاي الغلط الصغير ده ممكن يضيّع قروش في كل فاتورة، وإزاي تمنعه بسطر واحد.

المشكلة باختصار

افتح أي كونسول بايثون أو جافاسكريبت دلوقتي واكتب 0.1 + 0.2. مش هيطلعلك 0.3. هيطلعلك 0.30000000000000004. ده مش عطل في اللغة ولا في جهازك. ده سلوك متعمّد وموجود في كل لغة بتشتغل بأرقام عشرية عادية: بايثون، جافاسكريبت، Java، C.

لو ماعرفتش السبب، هتفضل تكتب كود بيقارن أرقام عشرية بـ == وبيفشل من غير ما تفهم ليه. ولو بتحسب فلوس، الانحراف ده بيتراكم.

الحكاية بمثال بسيط الأول

تخيّل إنك عايز تكتب "ثلث" بالأرقام العشرية. تقسم 1 على 3، يطلعلك 0.3333333... والتلاتات دي مش بتخلص أبدًا. الورقة اللي بتكتب عليها محدودة، فلازم توقف عند حد وتقرّب. يعني إنت أصلًا مش بتكتب "ثلث" بالظبط، إنت بتكتب رقم قريب منه.

الكمبيوتر بيعاني من نفس المشكلة بالظبط، بس مع أرقام مختلفة. هو مابيفكّرش بنظام العشرة زينا، هو بيفكر بنظام الاتنين. وفي نظام الاتنين، الرقم 0.1 بيتحوّل لكسر دوري لا ينتهي، تمامًا زي الثلث عندنا.

مقارنة بين استحالة تمثيل ثلث بالنظام العشري واستحالة تمثيل 0.1 بالنظام الثنائي لأن كليهما كسر دوري لا ينتهي

دلوقتي الشرح العلمي الدقيق

الكمبيوتر بيخزّن الأرقام العشرية بصيغة اسمها الفاصلة العائمة مزدوجة الدقة (double precision floating point)، ومعرّفة في معيار عالمي اسمه IEEE 754. الرقم بيتخزّن في 64 بت متقسّمة تلات أجزاء: بت واحد للإشارة، 11 بت للأس، و52 بت للأرقام نفسها (المانتيسا).

مخطط توزيع 64 بت في العدد العشري المزدوج بت واحد للإشارة و11 بت للأس و52 بت للمانتيسا أي نحو 15 خانة عشرية من الدقة

الـ 52 بت دول بيدّوك دقة حوالي 15 إلى 17 خانة عشرية بس. أي حاجة بعد كده بتتقرّب. المشكلة إن 0.1 في النظام الثنائي محتاج عدد لا نهائي من البتات عشان يتكتب بالظبط. فالكمبيوتر بيقرّبه لأقرب رقم يقدر يخزّنه. نفس الكلام مع 0.2. فلما تجمع رقمين مقرّبين، الغلط الصغير في كل واحد بيظهر في الناتج على شكل ...04 في الآخر.

جرّبها بنفسك بكود شغّال

في بايثون:

Python
>>> 0.1 + 0.2
0.30000000000000004

>>> 0.1 + 0.2 == 0.3
False

# جمع 0.1 عشر مرات المفروض يطلع 1.0
>>> sum(0.1 for _ in range(10))
0.9999999999999999

في جافاسكريبت نفس الحكاية:

JavaScript
0.1 + 0.2                 // 0.30000000000000004
0.1 + 0.2 === 0.3         // false

سيناريو واقعي: الفلوس

ركز في الحتة دي، لأنها اللي بتوجع فعلًا. لو عندك سيستم كاشير بيجمع أسعار، وكل صنف بـ 0.10 جنيه، ودخل 10 أصناف، إنت متوقع 1.00 جنيه. بالـ float هيطلعلك 0.9999999999999999. لوحده الفرق تافه. بس لو السيستم بيعمل ملايين العمليات في اليوم، ممكن تخسر مبالغ حقيقية على مدار الشهر.

الحل الأول: استخدم Decimal في بايثون، اللي بيحسب بالنظام العشري بالظبط:

Python
from decimal import Decimal

Decimal("0.1") + Decimal("0.2")   # النتيجة: Decimal('0.3') بالظبط

الحل التاني والأفضل للفلوس: خزّن كل حاجة بالقروش كأعداد صحيحة. الأعداد الصحيحة دقيقة 100% في الجمع والطرح:

Python
total_qirsh = 10 + 10 + 10   # 30 قرش، دقيق تمامًا
pounds = total_qirsh / 100   # 0.30 للعرض بس

وللمقارنة بين رقمين عشريين؟

متقارنش رقمين عشريين بـ == أبدًا. قارن الفرق بينهم بهامش صغير جدًا اسمه إبسيلون:

Python
EPS = 1e-9
if abs((0.1 + 0.2) - 0.3) < EPS:
    print("متساويين عمليًا")   # ده اللي هيطبع

في جافاسكريبت فيه ثابت جاهز اسمه Number.EPSILON بيعمل نفس الفكرة.

الـ trade-off: تكسب إيه وتخسر إيه

الـ float سريع جدًا وكفء في الذاكرة. ده اختيار ممتاز للرسوميات والفيزياء والحسابات العلمية. المكسب: سرعة. الخسارة: دقة عشرية مش مضمونة. الـ Decimal دقيق تمامًا بس أبطأ من float بحوالي 10 لـ 100 مرة حسب العملية. الأعداد الصحيحة (القروش) هي الأسرع والأدق للفلوس.

متى لا تستخدم float

ابعد عن float نهائيًا في: الفلوس والمحاسبة، أي مقارنة مساواة دقيقة، وأي حساب بيتراكم فيه الغلط عبر ملايين العمليات. في المقابل، float تمام في الحسابات العلمية وإحداثيات الرسم والنِسب اللي مش محتاجة دقة مطلقة.

الخطوة التالية

افتح كونسول بايثون دلوقتي واكتب sum(0.1 for _ in range(10)) وشوف الناتج بعينك. وبعدين لو مشروعك فيه أي فلوس متخزّنة كـ float، حوّلها لقروش صحيحة أو Decimal قبل ما تلاقي فرق في حساباتك ماتعرفش منين جه.

المصادر

  • معيار IEEE 754-2019 للحساب بالفاصلة العائمة.
  • توثيق بايثون الرسمي: Floating Point Arithmetic: Issues and Limitations — docs.python.org/3/tutorial/floatingpoint.html
  • David Goldberg, "What Every Computer Scientist Should Know About Floating-Point Arithmetic", ACM Computing Surveys, 1991.
  • توثيق MDN حول Number.EPSILON — developer.mozilla.org
  • توثيق بايثون لوحدة decimal — docs.python.org/3/library/decimal.html

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة