مثال بسيط، لنفترض أن لدينا متغيران a و b قيمتهما على التوالي 0.1 و 0.2 اذا جمع العددين كما درسنا في مادة الحساب 0.3
اي a + b == 03 يجب أن يكون true و هذا ما سيحدت عكسه في أغلب لغات البرمجة اذ سيكون الناتج false
السؤال المطروح للنقاش: ماسبب حدوث هذا. وكيف يتم حله في البرامج و الأنظمة الدقيقة (البورصة مثلا)
التعليقات
هي ليست غبية لكن كما تم الاشارة إليه في بعض التعليقات يعتمد المعالج على تمثيل الأعداد العشرية بطريقة اخرى. في العادة تستعمل المعالجات الرياضية المعيار المتبع من طرف IEEE لتمثيل هذه.
في حالة الأعداد العشرية نحن نميل إلى كتابة الأعداد على شكل رقم أٌس 10 مثلا 532e-10 يعني 532 اٌس -10
نفس الشيء بالنسبة للكمبيوتر, تمثل الأعداد على شكل أُس للعدد 2. في معالج 64bits يتم استخدام 52 بت لتمثيل الكسر, 11 بت لتمثيل الأس و 1 بت لتمثيل الاشارة.
---------------------+-----------------+-----------+
| الكسر | الأُس | الاشارة |
---------------------+----------------+------------+
0<------------->51 52<-------->62 63
يتم تمثيل العدد X على شكل : X= الكسر * 2 ^( الاُس - bias)
حيث يتم اظافة الـ bias لجعل قيم الأس موجبة, في حالة 64بت الـ bias = 1023.
في هذا التمثيل لما تقوم بمقارنة الأعداد الكسرة خاصة إذا استلزم الامر القيام بعملية قبلها لن يتساوى العددان بل سيكون فارق EPSILON صغير بينها.
لهذا في البرمجة يمكن أت تحدد الدقة التي تريدها (يعني كم عدد بعد الفاصلة لكي تتعتبر العددين متساويين)
EPSILON= 1.0e-20
a+b - 0.3 <= EPSLON
فعلاً التعامل مع الأرقام العشرية مع لغات البرمجة كلها غير مستقر والسبب هو صعوبة التحكم فى التقريب لأقرب رقم عشرى
فمثلا
System.out.println(2.0 - 1.1);
prints 0.8999999999999999
not 0.9
والسبب فى عدم التحكم فى دقة التقريب أن هذه الارقام تنوب عن الأرقام الثنائية للنظام, لذلك لو أردت أن تستخدم فى حساباتك نتائج واقعية أكثر استخدم الكلاس BigDecimal وهذا فى الجافا