سؤال

الكود التالي في C# لا يعمل:

int iValue = 0;
double dValue = 0.0;

bool isEqual = iValue.Equals(dValue);

إذن السؤال:ما هي أفضل طريقة لمقارنة Double و Int؟

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

المحلول

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

int iValue = 0;
double dValue = 0.0;

var diff = Math.Abs(dvalue - iValue);
if( diff < 0.0000001 ) // need some min threshold to compare floating points
   return true; // items equal

عليك حقا أن تحدد لنفسك ما equality يعني لك.على سبيل المثال، قد ترغب في تقريب قيمة الفاصلة العائمة إلى أقرب عدد صحيح، بحيث يكون 3.999999981 "يساوي" 4.أو قد ترغب في اقتطاع القيمة، بحيث تكون فعليًا 3.كل هذا يتوقف على ما تحاول تحقيقه.

يحرر: لاحظ أنني اخترت 0.0000001 كمثال لقيمة الحد ...عليك أن تقرر بنفسك ما هي الدقة الكافية للمقارنة.فقط أدرك أنك بحاجة إلى أن تكون ضمن الحدود التمثيلية الطبيعية double الذي أعتقد أنه تم تعريفه على أنه Double.Epsilon.

نصائح أخرى

وانها فكرة سيئة للغاية مقارنة الأعداد الصحيحة وأرقام الفاصلة العائمة من أجل المساواة في أي لغة. كان يعمل لحالات بسيطة جدا، ولكن بعد قيام بأي الرياضيات في كل شيء، وlikliehood البرنامج تفعل ما تريد أن يقلل بشكل كبير.

وعليها أن تفعل مع الطريقة التي يتم بها تخزين أرقام الفاصلة العائمة على نظام ثنائي، والرقمية.

إذا كنت متأكدا جدا كنت تريد استخدام هذا، إنشاء فئة لجعل كنت تملك عدد مع الكسور. استخدام كثافة واحدة للحفاظ على عدد صحيح، وآخر للحفاظ على كثافة العمليات الكسر.

وهذا يعتمد حقا على ما كنت تنظر "على قدم المساواة". إذا كنت تريد المقارنة الخاصة بك للعودة صحيحا إذا وفقط إذا كان ضعف مباريات بالضبط قيمة عدد صحيح (أي لا يوجد لديه عنصر كسور)، يجب أن يلقي الباحث إلى مزدوج للقيام بهذه المقارنة:

bool isEqual = (double)iValue == dValue;

إذا شيء من هذا القبيل 1.1 سيعتبر يساوي 1، يمكنك إما يلقي ضعف إلى int (إذا كنت ترغب في تجاهل المكون كسور تماما) أو جولة ضعف إذا كنت تريد القول 1.9 يساوي 2.

double val1 = 0;
double val2 = 0.0;
if((val1 - Double.Epsilon) < 0)
{
    // Put your code here
}

      OR

if((val2 - Double.Epsilon) < 0)
{
    // Put your code here
}

وحيث Double.Epsilon هو أدنى قيمة ممكنة للنقرا.

في أيامنا هذه، مجرد المرة الوحيدة التي ينبغي للمرء أن يكون مقارنة القيم من أنواع double وإما integer أو long عن المساواة التامة وعندما، لسبب ما، واحد هو تخزين عالقة أو تمرير كميات لا يتجزأ كقيم الفاصلة العائمة في وقت لاحق يحتاج إلى تحويلها إلى الوراء. هذا التحويل قد تكون في معظم الحالات يتم إنجاز بسهولة عن طريق الصب نوع جزءا لا يتجزأ من double، ومن ثم مقارنة نتيجة لذلك المدلى بها. لاحظ أن التحويل من long إلى double قد يكون غير دقيق إذا كان الرقم خارج نطاق ± 2 <سوب> 52 . ومع ذلك، في الأيام التي سبقت أصبح 64 بت long المتاحة، كان double نوع تخزين مفيد لكميات عددية التي كانت كبيرة جدا لint 32 بت ولكن صغيرة بما فيه الكفاية ليتم التعامل معها من قبل double.

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

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