تحليل
يحتوي JavaScript على رقم نوع واحد فقط ، ويتم تمثيل جميع الأرقام في JavaScript بتنسيق IEEE-754 القياسي. مشكلة الدقة المتمثلة في أرقام النقطة العائمة ليست فريدة من نوعها بالنسبة إلى JavaScript ، لأن بعض العشرية تمثل أرقامًا لا حصر لها في الثنائي:
عشري ثنائي
0.1 0.0001 1001 1001 1001 ...
0.2 0.0011 0011 0011 0011 ...
0.3 0.0100 1100 1100 1100 ...
0.4 0.0110 0110 0110 0110 ...
0.5 0.1
0.6 0.1001 1001 1001 1001 ...
على سبيل المثال ، 1.1 ، لا يمكن أن يمثل برنامجه "1.1" ، ولكن لا يمكن إلا أن يحقق درجة معينة من الدقة.
1.09999999999999999
المشكلة في JavaScript أكثر تعقيدًا ، وهنا هناك فقط بعض بيانات الاختبار في Chrome:
المدخلات والمخرجات
1.0-0.9 == 0.1 خطأ
1.0-0.8 == 0.2 خطأ
1.0-0.7 == 0.3 خطأ
1.0-0.6 == 0.4 صحيح
1.0-0.5 == 0.5 صحيح
1.0-0.4 == 0.6 صحيح
1.0-0.3 == 0.7 صحيح
1.0-0.2 == 0.8 صحيح
1.0-0.1 == 0.9 صحيح
يحل
فكيف تجنب هذا النوع من مشكلة عدم وجود bug مع 1.0-0.9! = 0.1؟ فيما يلي حل يستخدم حاليًا بشكل متكرر.
نسخة الكود كما يلي:
(1.0-0.9) .Tofixed (أرقام) // tofixed () يجب أن تكون معلمات الدقة بين 0 و 20
parsefloat ((1.0-0.9) .Tofixed (10)) === 0.1 // النتيجة صحيحة
parsefloat ((1.0-0.8) .Tofixed (10)) === 0.2 // النتيجة صحيحة
parsefloat ((1.0-0.7) .Tofixed (10)) === 0.3 // النتيجة صحيحة
Parsefloat ((11.0-11.8) .Tofixed (10)) === -0.8 // النتيجة صحيحة
طريقة تكرير
نسخة الكود كما يلي:
// استخدم طريقة أداة isequal لتحديد ما إذا كانت القيم متساوية أم لا
وظيفة isequal (الرقم 1 ، الرقم 2 ، الأرقام) {
الأرقام == غير محددة؟
إرجاع رقم 1.Tofixed (الأرقام) === number2.tofixed (الأرقام) ؛
}
isequal (1.0-0.7 ، 0.3) ؛
// طريقة التمديد الأصلي ، تفضل النمط الموجهة للكائنات
number.prototype.isequal = الدالة (الرقم ، الأرقام) {
الأرقام == غير محددة؟
إرجاع this.tofixed (الأرقام) === number.tofixed (الأرقام) ؛
}
(1.0-0.7) .eSequal (0.3) ؛