لماذا يعطي Splint (مدقق كود C) خطأً عند مقارنة التعويم بـ int؟

StackOverflow https://stackoverflow.com/questions/38027

  •  09-06-2019
  •  | 
  •  

سؤال

كلاهما قيم رياضية، ولكن التعويم لديه دقة أكبر.هل هذا هو السبب الوحيد للخطأ - الفرق في الدقة؟أم أن هناك مشكلة أخرى محتملة (وأكثر خطورة)؟

هل كانت مفيدة؟

المحلول

ذلك لأن مجموعة القيم الصحيحة لا تساوي مجموعة القيم العائمة للنوعين "int" و"float".على سبيل المثال، القيمة العائمة 0.5 ليس لها مثيل في مجموعة الأعداد الصحيحة وقد لا تكون قيمة العدد الصحيح 4519245367 موجودة في مجموعة القيم التي يمكن أن يخزنها العائم.لذلك، يقوم المدقق بوضع علامة على هذا كمشكلة يجب التحقق منها بواسطة المبرمج.

نصائح أخرى

لأنها ربما ليست فكرة جيدة جدًا.لا يمكن اقتطاع كل العوامات إلى ints؛لا يمكن تحويل كل ints إلى عوامات.

عند إجراء المقارنة، سيتم "ترقية" القيمة الصحيحة إلى قيمة النقطة العائمة.عند هذه النقطة، فأنت تقوم بإجراء مقارنة مساواة دقيقة بين رقمين عائمين، وهو أمر سيئ دائمًا تقريبًا.

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

int double_equals(double a, double b, double epsilon)
{
   return ( a > ( b - epsilon ) && a < ( b + epsilon ) );
}

إذا لم يكن لتطبيقك خيار واضح لـ epsilon، فاستخدم DBL_EPSILON.

نظرًا لأن العوامات لا يمكنها تخزين قيمة int دقيقة، لذلك إذا كان لديك متغيرين، int i وfloat f، حتى لو قمت بتعيين "i = f;"، فإن المقارنة "if (i == f)" ربما لن تكون كذلك العودة صحيحا.

بافتراض الأعداد الصحيحة الموقعة وتنسيق النقطة العائمة IEEE، فإن مقادير الأعداد الصحيحة التي يمكن تمثيلها هي:

short  -> 15 bits
float  -> 23 bits
long   -> 31 bits
double -> 52 bits

ولذلك أ float يمكن أن تمثل أي short و أ double يمكن أن تمثل أي long.

إذا كنت بحاجة إلى التغلب على هذا (لديك سبب مشروع وتشعر بالسعادة لأن أيًا من المشكلات المذكورة في الإجابات الأخرى لا تمثل مشكلة بالنسبة لك) فما عليك سوى الانتقال من نوع إلى آخر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top