كيف يمكنني إجبار 0.0/0.0 على العودة صفر بدلاً من NAN في برنامج التحويل البرمجي Mipspro C؟

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

  •  23-09-2019
  •  | 
  •  

سؤال

كما ينص السؤال ، أنا أستخدم برنامج التحويل البرمجي Mipspro C ، ولدي عملية تُرجع NAN لبعض مجموعات البيانات حيث يكون كل من البسط والفضيل صفراً. كيف يمكنني منع هذا من الحدوث؟

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

المحلول

على أنظمة SGI باستخدام برنامج التحويل البرمجي Mipspro ، يمكنك ضبط معالجة استثناءات النقطة العائمة المختلفة بدقة كبيرة باستخدام المرافق في sigfpe.h. كما يحدث ، فإن تقسيم الصفر بواسطة الصفر هو إحدى هذه الحالات:

#include <stdio.h>
#include <sigfpe.h>

int main (void) {
    float x = 0.0f;
    (void) printf("default %f / %f = %f\n", x, x, (x / x));
    invalidop_results_[_ZERO_DIV_ZERO] = _ZERO;
    handle_sigfpes(_ON, _EN_INVALID, 0, 0, 0);
    (void) printf("handled %f / %f = %f\n", x, x, (x / x));
    return 0;
}

في الاستخدام:


arkku@seven:~/test$ cc -version
MIPSpro Compilers: Version 7.3.1.3m
arkku@seven:~/test$ cc -o sigfpe sigfpe.c -lfpe
arkku@seven:~/test$ ./sigfpe
default 0.000000 / 0.000000 = nan0x7ffffe00
handled 0.000000 / 0.000000 = 0.000000

كما ترون ، قم بتعيين ملف _ZERO_DIV_ZERO النتيجة تغير نتيجة نفس الانقسام. وبالمثل ، يمكنك التعامل مع التقسيم العادي حسب الصفر (على سبيل المثال إذا كنت لا تريد اللانهاية كنتيجة).

بالطبع ، لا شيء من هذا هو المعيار. سيكون من الممكن التحقق من NAN بعد كل قسم وحتى أفضل من التحقق من الأصفار من قبل. يوفر C99 بعض السيطرة على بيئة النقطة العائمة في fenv.h, ، لكنني لا أعتقد أن أي شيء مناسب لهذا متاح. في أي حال ، لا يدعم Mipspro القديم الخاص بي C99.

نصائح أخرى

استخدم جملة if؟ أنا أيضًا أشعر بالفضول لماذا تريد تجاهل هذا الاستحالة الرياضية. أنت متأكد من أن مدخلاتك ليست خاطئة/لا معنى لها في هذه الحالة؟

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

DBL_MIN هو أصغر مزدوج

DBL_EPSILON هو أصغر ST X+DBL_EPSILON! = x

لذلك سأحاول

#include <float.h>
#define EPS DBL_MIN

double divModified(double num, double denom) {
    return num / (denom + EPS);
}

IEEE 754 (المواصفات الخاصة بالنقطة العائمة) تقول إن 0.0/0.0 ليس رقمًا ، أي NaN. إذا كنت تريد أن يكون أي شيء آخر ، فإن أفضل طريقة إلى حد بعيد هو اكتشاف عندما تكون المعاملات صفرًا في if بند وإرجاع القيمة التي تفضل تقديمها. ربما مثل هذا:

#define WonkyDiv(a,b)  ((a)==0.0&&(b)==0.0 ? 0.0 : (a)/(b))

float wonkyResult = WonkyDiv(numerator, denominator);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top