لماذا أستخدم مكمل 2 لمقارنة اثنين من الزوجي بدلاً من مقارنة اختلافاتهما بقيمة إبسيلون؟

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

  •  01-07-2019
  •  | 
  •  

سؤال

المشار إليه هنا و هنا...لماذا أستخدم المكمل الثنائي بدلاً من طريقة إبسيلون؟يبدو أن طريقة إبسيلون ستكون جيدة بما يكفي لمعظم الحالات.


تحديث: أنا أبحث تمامًا عن سبب نظري لاستخدام أحدهما على الآخر.لقد استخدمت دائمًا طريقة إبسيلون.

هل استخدم أي شخص المقارنة التكميلية 2 بنجاح؟لماذا؟ولم لا؟

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

المحلول

يشير الرابط الثاني الذي تشير إليه إلى مقالة تحتوي على وصف طويل للمشكلة:

http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

ولكن ما لم تكن تقوم بتعديل الأداء، فسألتزم بإبسيلون حتى يتمكن الأشخاص من تصحيح التعليمات البرمجية الخاصة بك

نصائح أخرى

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

باختصار، عند مقارنة عوامات مجهولة المصدر، فإن اختيار إبسيلون صالح يكاد يكون مستحيلًا.

على سبيل المثال:

ما هو إبسيلون الجيد عند مقارنة المسافة بالأميال بين أتلانتا GA ودالاس تكساس ومكان ما في أوهايو؟

ما هو إبسيلون الجيد عند مقارنة المسافة بالأميال بين قدمي اليسرى وقدمي اليمنى والكمبيوتر الموجود أسفل مكتبي؟

يحرر:

حسنًا، لدي عدد لا بأس به من الأشخاص الذين لا يفهمون سبب عدم معرفتك ما هو إبسيلون الخاص بك.

بالعودة إلى الأيام الخوالي، كتبت برنامجين يعملان مع NeverWinter Nights (لعبة من إنتاج BioWare).أخذ أحد البرامج نموذجًا ثنائيًا وقام بتحويله إلى ASCII.أخذ البرنامج الآخر نموذج ASCII وقام بتجميعه في ملف ثنائي.كان أحد الاختبارات التي كتبتها هو أخذ كافة نماذج BioWare الثنائية، وفك ترجمتها إلى ASCII ثم إعادتها إلى النظام الثنائي.ثم قمت بمقارنة نسختي الثنائية بالنسخة الأصلية من BioWare.إحدى المشاكل أثناء المقارنة كانت التعامل مع بعض الفروق الطفيفة في قيم الفاصلة العائمة.لذلك بدلاً من التوصل إلى مجموعة من أرقام EPSILONS المختلفة لكل نوع من أرقام الفاصلة العائمة (الرأس، العادي، وما إلى ذلك)، أردت استخدام شيء مثل هذه المقارنة الثنائية المجاملة.وبالتالي تجنب مشكلة EPSILON المتعددة بالكامل.

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

يحرر:

لول، لقد تم التصويت على هذا صعودا وهبوطا من قبل أشخاص مختلفين.

سألخص المشكلة في هذا، في ضوء اثنين اِعتِباطِيّ أرقام الفاصلة العائمة، كيف يمكنك أن تقرر ما هو إبسيلون الذي ستستخدمه؟لا يمكنك.

كيف يمكنك مقارنة 1e23 و1.0001e23 مع إبسيلون وما زلت تقارن 1e-23 و5.2e-23 باستخدام نفس إبسيلون؟بالتأكيد، يمكنك القيام ببعض حيل إبسيلون الديناميكية، ولكن هذا هو بيت القصيد من مقارنة الأعداد الصحيحة (والتي لا تتطلب أن تكون الأعداد الصحيحة دقيقة).

مقارنة الأعداد الصحيحة قادرة على مقارنة عددين من العوامات باستخدام إبسيلون بالنسبة لحجم الأرقام.

يحرر

ستيف، دعنا نلقي نظرة على ما قلته في التعليقات:

"لكنك تعرف ماذا تعني المساواة بالنسبة لك...ومن ثم، يجب أن تكون قادرًا على العثور على إبسيلون مناسب".

اقلب هذا البيان ليقول:

"إذا كنت تعرف ما تعنيه المساواة بالنسبة لك، فيجب أن تكون قادرًا على العثور على إبسيلون مناسب."

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

عندما يتعلق الأمر بالسرعة، اتبع هذه القواعد:

  1. إذا لم تكن مطورًا ذا خبرة كبيرة، فلا تقم بالتحسين.
  2. إذا كنت مطورًا ذا خبرة، فلا تقم بالتحسين بعد.

قم بأسهل طريقة.

أليكس

أوسكار على حق.لا تعبث بهذا إلا إذا كنت حقًا بحاجة إلى هذا الأداء.

وأنت لا تفعل ذلك.إذا كنت في الموقف الذي حدث، فلن تحتاج إلى طرح السؤال - كنت تعرف بالفعل.إذا كنت تعتقد أنك تفعل، فأنت لا تفعل ذلك.مشاكل الأداء لديك تكمن في مكان آخر.مجرد استخدام النسخة القابلة للقراءة.

سيؤدي استخدام أي طريقة للمقارنة بين وحدات البت إلى حدوث مشكلة عند تمثيل الكسور بالتقريب.جميع أرقام الفاصلة العائمة ذات الكسور غير المقومة بقوى العدد اثنين (1/2، 1/4، 1/8، 1/65536، &c) يتم تقريبها.لذا، بالطبع، كلها أعداد غير نسبية.

تعويم الثالث = 1/3؛تعويم اثنين = 2.0؛تعويم آخر_اثنين=ثالث*6.0;if (اثنين! = other_two) print ("التقريب! n") ؛

المرة الوحيدة التي ستنجح فيها المقارنة بين وحدات البت هي عندما تشتق أرقام الفاصلة العائمة بنفس الطريقة تمامًا أو تكون تمثيلات دقيقة (أرقام صحيحة، قوى كسرية لاثنين).وحتى في هذه الحالة، يمكن أن يكون هناك تمثيلات متعددة لبعض الأرقام، على الرغم من أنني لم أر هذا من قبل في نظام العمل.

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