سؤال

بعد النظر في سؤال آخر على ذلك (باستخدام NAN في C ++) أصبحت فضولية std::numeric_limits<double>::signaling_NaN().

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

ها هو رمزتي:

double my_nan = numeric_limits<double>::signaling_NaN();
my_nan++;
my_nan += 5;
my_nan = my_nan / 10;
my_nan = 15 / my_nan;
cout << my_nan << endl;

numeric_limits<double>::has_signaling_NaN يقيم إلى صحيح ، لذلك يتم تنفيذه على نظامي.

أيه أفكار؟

أنا أستخدم MS Visual Studio .NET 2003's C ++ برنامج التحويل البرمجي. أريد اختباره على آخر عندما أصل إلى المنزل.

شكرًا!

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

المحلول

يمكنك استخدام ال _control87() وظيفة لتمكين استثناءات نقطة العائمة. من وثائق MSDN على _control87():

ملحوظة:

تقوم مكتبات وقت التشغيل بإخفاء جميع استثناءات نقطة العائمة بشكل افتراضي.

عند تمكين استثناءات النقطة العائمة ، يمكنك استخدام signal() أو SEH (معالجة استثناء منظم) للقبض عليهم.

نصائح أخرى

كلمة تحذير: قد يؤدي استخدام DLLs الطرف الثالث إلى تمكين هذه الاستثناءات بصمت. هذا صحيح بشكل خاص لتحميل DLL المكتوبة بلغة تمكنهم افتراضيًا.

لقد حدث ذلك في حالتين: الطباعة من عنصر تحكم المتصفح المدمج إلى طابعة HP ، وتسجيل DLL الخاص بي (الذي يحدد بعض القيم الأولية إلى NAN) من Innosetup المكتوبة في Delphi.

المفتاح يكمن في numeric_limits<T>::has_signaling_NaN. ما هي القيمة التي يتمتع بها هذا بالنسبة لك؟ (يبدو أن MSDN تشير إلى أنه دائمًا false لـ MSVC؟)

من TFM:

cout << "The signaling NaN for type float is:  "
    << numeric_limits<float>::signaling_NaN( )
    << endl;

->

الإشارة نان لطفو النوع هو: 1.#qnan

حيث "Q" تعني "هادئ". Dunno لماذا سيعود ذلك ، ولكن لهذا السبب لا يلقي استثناء لك.

بدافع الفضول ، هل هذا يعمل بشكل أفضل؟

const double &real_snan( void )
{
    static const long long snan = 0x7ff0000080000001LL;
    return *(double*)&snan;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top