سؤال

أنا أفعل بعض النقطة العائمة الحساب ولديها مشاكل دقيقة. تختلف القيمة الناتجة عن أجهزتين لنفس الإدخال. قرأت المنشور @ لماذا لا يمكنني مضاعفة تعويم؟ وأيضًا اقرأ مواد أخرى على الويب وفهم أن الأمر يتعلق بالتمثيل الثنائي للنقطة العائمة وعلى آلات Epsilon. ومع ذلك ، أردت التحقق مما إذا كانت هناك طريقة لحل هذه المشكلة / بعض العمل من أجل حساب النقطة العائمة في C ++؟ أقوم بتحويل تعويم إلى قصير غير موقّع للتخزين وأتحول مرة أخرى عند الضرورة. ومع ذلك ، عندما أقوم بتحويلها إلى قصيرة غير موقعة ، تظل الدقة (إلى 6 نقاط عشرية) صحيحة على جهاز واحد ولكنها تفشل من جهة أخرى.

//convert FLOAT to short

unsigned short sConst = 0xFFFF;

unsigned short shortValue = (unsigned short)(floatValue * sConst);

//Convert SHORT to FLOAT

float floatValue = ((float)shortValue / sConst);
هل كانت مفيدة؟

المحلول

أ short يجب أن يكون ما لا يقل عن 16 بت ، وفي مجموعة كبيرة من التطبيقات بالضبط ما هو عليه. و unsigned 16 بت short سوف يحمل القيم من 0 إلى 65535. وهذا يعني أن القصير لن يحمل خمسة أرقام كاملة من الدقة ، وبالتأكيد ليس ستة. إذا كنت تريد ستة أرقام ، فأنت بحاجة إلى 20 بت.

لذلك ، من المحتمل أن يكون أي فقدان للدقة بسبب حقيقة أنك تحاول حزم ستة أرقام من الدقة في شيء أقل من خمسة أرقام. لا يوجد حل لهذا ، بخلاف استخدام نوع متكامل ربما يتطلب الكثير من التخزين مثل float.

لا أعرف لماذا يبدو أنه يعمل على نظام واحد. هل كنت تستخدم نفس الأرقام على كليهما؟ هل استخدم المرء نظامًا عائمًا أقدم ، ونظامًا أعطى بالصدفة النتائج التي كنت تتوقعها على العينات التي جربتها؟ هل كان من المحتمل أن تستخدم أكبر short من الآخر؟

نصائح أخرى

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

يعتمد التعريف الدقيق لـ "أكثر من اللازم" بالكامل على تطبيقك. على سبيل المثال ، إذا قمت بحساب a + b على منصات مختلفة ، يجب أن تجد النتيجتين ضمن دقة الماكينة لبعضهما البعض. من ناحية أخرى ، إذا كنت تفعل شيئًا أكثر تعقيدًا مثل انعكاس المصفوفة ، فمن المرجح أن تختلف النتائج بأكثر من دقة الجهاز. إن تحديد مدى قربك بدقة أن تتوقع أن تكون النتائج لبعضها البعض عملية خفية ومعقدة للغاية. ما لم تكن تعرف بالضبط ما تفعله ، فمن المحتمل أن يكون أكثر أمانًا (وسانر) تحديد مقدار الدقة التي تحتاجها في اتجاه المصب في تطبيقك والتحقق من أن النتيجة دقيقة بما فيه الكفاية.

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

وظائف مقارنة نقطة العائمة لـ C#

بدلاً من استخدام 0xFFFF ، استخدم نصفه ، أي 32768 للتحويل. 32768 (OX8000) لديه تمثيل ثنائي قدره 100000000000000000 ، في حين أن OXFFFF لديه تمثيل ثنائي من 111111111111111. إن التمثيل الثنائي OX8000 يعني بوضوح ، لن يتغير عمليات الضرب والفرق أثناء التحويل (أو) مع الترويج إلى التطفو) قيم الدقة) بعد الصفر. لتحويل جانبي واحد ، ومع ذلك ، فإن Oxffff هو الأفضل ، لأنه يؤدي إلى نتيجة أكثر دقة.

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