لماذا ناتج 0.1 + 0.2 هو 0.30000000000000004

لماذا يجعل نظام الفاصلة العائمة الثنائي ناتج 0.1 زائد 0.2 يظهر كـ0.30000000000000004، وكيف تعيد هذه الآلة الحاسبة تقريبه إلى 0.3 نظيف.

اكتب 0.1 + 0.2 في أي آلة حاسبة تقريبًا تعمل بنظام الفاصلة العائمة الثنائي، وستحصل على الناتج الخام 0.30000000000000004، وليس 0.3. هذه الآلة الحاسبة تنتج داخليًا القيمة نفسها، ثم تقرّبها عند العرض، لذا تراها كـ0.3. السبب هو عدم توافق بين الأنظمة العددية: البشر يكتبون الأعداد في الأساس 10، بينما الحواسيب تخزّنها في الأساس 2، والعدد 0.1 لا يمكن تمثيله بدقة تامة في الأساس 2.

أهم النقاط

  • ناتج 0.1 + 0.2 هو 0.30000000000000004 في نظام الفاصلة العائمة الثنائي، في كل لغة برمجة.
  • العدد 0.1 في الثنائي هو نمط متكرر، 0.0001100110011….
  • هذه الآلة الحاسبة تقرّب النتائج إلى 12 رقمًا معنويًا، لذا تعرض 0.3، وليس القيمة الخام مضاعفة الدقة.
  • القيمة المخزَّنة فعليًا للعدد 0.1 هي 0.10000000000000000555111512312578….

من أين تأتي الأرقام الزائدة

تعرف بالفعل أن بعض الكسور لا تُكتب بدقة في الأساس 10. الثلث هو 0.333…، متكرر إلى ما لا نهاية، لأن 3 ليس عاملًا من عوامل 10. الحواسيب تخزّن الأعداد في الأساس 2، حيث الكسور النظيفة الوحيدة هي التي يكون مقامها قوة من قوى العدد 2: النصف، الربع، الثمن. العُشر ليس ضمن هذه القائمة. في الثنائي، العدد 0.1 هو 0.0001100110011…، متكرر إلى ما لا نهاية، تمامًا كما يتكرر الثلث في العشري.

العدد ذو الدقة المضاعفة (double-precision) يملك 53 بت لتمثيل الأرقام، لذا يُقطع التمثيل الثنائي اللانهائي عند حد معين. القيمة المخزَّنة عندما تكتب 0.1 هي 0.1000000000000000055511151231257827021181583404541015625. وهي قريبة من 0.1 لكنها ليست مساوية له تمامًا. عند جمع قيمتين منحرفتين قليلًا كهاتين، لا يُلغي الخطأ نفسه، بل يتراكم، فينتهي المجموع عند خطوة واحدة بعد 0.3. ومن هنا يظهر 0.30000000000000004. هذا هو معيار IEEE 754، المطبَّق عمليًا في كل معالج ولغة برمجة تقريبًا، لذا تظهر النتيجة نفسها في JavaScript وPython وC وExcel.

ماذا تفعل هذه الآلة الحاسبة حيال ذلك

القاعدة المعتمدة في هذا الموقع موضّحة في دليل حساب الفاصلة العائمة: كل نتيجة تُقرَّب إلى 12 رقمًا معنويًا قبل عرضها. العدد مضاعف الدقة يحمل نحو 15 إلى 17 رقمًا موثوقًا، لذا فإن التقريب عند 12 يحافظ على كل رقم يمكن الوثوق به، ويحذف الأرقام القليلة الأخيرة، وهي بالضبط المكان الذي يتراكم فيه الخطأ.

مثال محلول 1: جرّب بنفسك. في الآلة الحاسبة الرئيسية، اكتب 0.1+0.2. يعرض الشاشة 0.3. القيمة الفعلية مضاعفة الدقة هي 0.30000000000000004، لكن قاعدة العرض تخفيها. طبّق الحيلة نفسها في الاتجاه المعاكس مع 0.3-0.2: الناتج الخام هو 0.09999999999999998، وتعرض الشاشة 0.1. الضرب يفعل الشيء نفسه: 1.1*3 تحمل قيمة 3.3000000000000003 وتعرض 3.3.

عندما يتعذّر فعلًا تحديد الناتج بدقة، لا تتظاهر الآلة الحاسبة بخلاف ذلك. اكتب 1/3 فتظهر 0.333333333333، اثنا عشر رقم “3” ثم تتوقف. يشرح دليل الأرقام المعنوية بالتفصيل كيف يعمل هذا التقريب وحدود العرض هذه.

متى يكون الفرق مهمًا

في الحسابات اليومية والواجبات المدرسية والتقديرات الهندسية، توفّر 12 رقمًا موثوقًا دقة أكبر بكثير مما يبرره أي قياس. الفرق يصبح مهمًا في ثلاث حالات محدودة، جميعها موضّحة في دليل حساب الفاصلة العائمة:

  • الأموال. لا تخزّن العملة كعدد ذي فاصلة عائمة. تمثيل البنسات أو السنتات كأعداد صحيحة كاملة هو الطريقة الآمنة، وتراكم الأخطاء الصغيرة عبر المجاميع الجارية نوع معروف من أخطاء المحاسبة.
  • اختبارات المساواة في البرمجة. اختبار ما إذا كانت قيمتان عشريتان محسوبتان متساويتين تمامًا أمر غير موثوق؛ قارن بدلًا من ذلك بهامش تسامح صغير.
  • سلاسل العمليات الطويلة. الأخطاء تتراكم، وطرح عددين متقاربين جدًا يفقد أكبر قدر من الدقة.

مثال محلول 2: كسور دقيقة تمامًا. عندما تحتاج إلى كسر صحيح تمامًا، تحافظ آلة حساب الكسور على البسط والمقام كأعداد صحيحة ولا تقرّب أبدًا. اكتب 1/3 + 1/3 + 1/3 فيها فتحصل بالضبط على 1. أجرِ الجمع نفسه بالأعداد العشرية المعروضة، 0.333333333333 + 0.333333333333 + 0.333333333333، وستحصل على 0.999999999999. الفكرة نفسها، لكن في عالمين مختلفين.

مثال محلول 3: الجذور والتربيع. sqrt(2)^2 فخ كلاسيكي معروف. منطقيًا، الجذر التربيعي للعدد 2 مربّعًا يساوي 2. في الآلة الحاسبة، الناتج الخام هو 2.0000000000000004، ويُقرَّب عند العرض إلى 2. عندما تحتاج إلى القيمة الدقيقة، أبقِ صيغة الجذر واحسبها مرة واحدة في النهاية، وهو ما يناقشه مرجع دوال الآلة الحاسبة تحت مفتاح √.

هناك أيضًا حد فاصل للأعداد الصحيحة يستحق المعرفة. تحت 2^53 − 1 = 9,007,199,254,740,991، يمكن تمثيل كل عدد صحيح بدقة تامة، وتطبع الآلة الحاسبة كل أرقامه. فوق هذا الحد، تتحول قيم مثل 19! إلى الترميز العلمي بدلًا من ادعاء دقة غير موجودة فعليًا.

أسئلة شائعة

هل ناتج 0.1 زائد 0.2 هو فعلًا 0.3 أم لا؟

في الحساب العشري الدقيق، نعم هو كذلك. أما في نظام الفاصلة العائمة الثنائي، فالنتيجة المخزَّنة هي 0.30000000000000004. هذه الآلة الحاسبة تُرجع القيمة نفسها داخليًا وتقرّبها إلى 12 رقمًا معنويًا عند العرض، لذا تراها كـ0.3.

هل هذا خلل في الآلة الحاسبة؟

لا. هذا هو معيار IEEE 754 الذي يطبّقه كل معالج ولغة برمجة رئيسية تقريبًا. البرامج والآلات الحاسبة التي تبدو وكأنها تتجنب هذه المشكلة تخفيها فعليًا عبر تقريب العرض، تمامًا كما تفعل هذه الآلة.

كيف أحصل على إجابة دقيقة تمامًا؟

استخدم آلة حساب الكسور للحساب النسبي، الذي لا يقرّب أبدًا، أو أبقِ الصيغ الرمزية مثل sqrt(2) وpi في التعبير حتى الخطوة الأخيرة.

لماذا يظهر ناتج 1 مقسومًا على 3 باثني عشر رقم “3” فقط؟

لأن الثلث ليس له تمثيل دقيق تمامًا في أي من النظامين العددين. تعرض الآلة الحاسبة اثني عشر رقمًا موثوقًا ثم تتوقف، بدلًا من الادّعاء بأن القيمة تنتهي فعليًا.