كيفية إعلان الوظائف الرياضية IEEE مثل "ilogbf" في MSVC ++ 6؟

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

  •  19-09-2019
  •  | 
  •  

سؤال

هل يمكن لشخص ما الرجاء المساعدة وأخبرني كيف تتضمن وظائف IEEE الرياضية في MSVC ++ 6؟ جربت كليهما، لكنني ما زلت أحصل على هذه الأخطاء:

خطأ C2065: 'ilogbf': معرف غير محدد

خطأ C2065: "SCALBNF": معرف غير محدد

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

المحلول

تحرير 3: نأمل أن يكون هذا تحريري النهائي. لقد جئت إلى أن أدرك أنني لم أعالج هذا السؤال بشكل صحيح على الإطلاق. سأترك إجابتي في مكان كحصة تحذيرية، ولأنها قد يكون لها بعض القيمة التعليمية. لكنني أفهم لماذا لدي صفر upvotes، وفي الواقع أنا ذاهب إلى رفع رسوم andy ross "لأنني أعتقد أنه أكثر صلة بكثير (على الرغم من أنه غير مكتمل على الأقل في وقت الكتابة). يبدو لي أن خطأي كان يأخذ التعريفات الرجل التي عثرت عليها ل ILOGBF () بسطحية قليلا. إنها وظيفة تأخذ الجزء عدد صحيح من سجل تعويم، ما مدى صعوبة تنفيذ ذلك؟ اتضح أن الوظيفة هي حقا حول تمثيل نقطة عائمة IEEE، ولا سيما الأسس (على عكس Mantissa) جزء من هذا التمثيل. بالتأكيد يجب أن أدرك أنه قبل محاولة الإجابة على السؤال! نقطة مثيرة للاهتمام بالنسبة لي هي كيف يمكن أن تجد الوظيفة الجزء الأساسي من تعويم، حيث اعتقدت أن قاعدة أساسية م من C هي أن العوامات يتم ترقيتها إلى الزوجي كجزء من مكالمة دالة. لكن هذا مناقشة منفصلة كاملة بالطبع.

--- نهاية تحرير 3، بدء الحكاية الحذرية ---

تشير القليل من googling إلى أن هذه موجودة مع تحديدها في بعض النكهات من يونيكس، ولكن ربما لا تكون في أي بوسيكس أو قياسي ANSI ولذا غير مزود بمكتبات MSVC. إذا لم تكن الوظائف في المكتبة، فلن يتم الإعلان عنها في الرياضيات من الواضح أنه إذا كان التحويل البرمجي لا يستطيع رؤية تصريحات لهذه الرموز الخارجية لن يكون سعيدا وستحصل على أخطاء مثل تلك التي تقوم بها.

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

#include <math.h>

int ilogbf( float f )
{
    double d1 = (double)f;
    double d2 = log(d1);
    int ret = (int)d2;
    return ret;
}

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

جوهر إجابتي، أي أن ANSI C لا يتطلب هذه الوظيفة وأن MSVC لا تتضمن ذلك، هو الصحيح على ما يبدو.

تحرير 2: حسنا لقد أضعفت وتوفير نسخة محسنة دون أن يتم طرحها. ها هو؛

#include <math.h>

int ilogbf( float f )
{
    double d1 = (double)f;
    if( d1 < 0 )
        d1 = -d1;
    double d2 = log(d1) / log(2);  // log2(x) = ln(x)/ln(2)
    int ret = (int)d2;
    return ret;
}

نصائح أخرى

هذه هي وظائف C99، وليس IEEE754-1985. يبدو أن Microsoft قررت أن سوقهم لا يهتم بدعم C99، لذلك لم يزعجهم لتزويدهم. هذا عار، ولكن ما لم يشكو المزيد منكم (المطورين)، فلا يوجد سبب لتوقع أن يتغير الوضع.

تتطلب معيار العلامة التجارية الجديدة 754، IEEE754-2008، هذه الوظائف (الفقرة 5.3.3، "عمليات LogbFormat")، لكن هذا الإصدار من المعيار لن يتم اعتماده على نطاق واسع لعدة سنوات أخرى؛ حتى لو كان الأمر يتعلق باعتماد واسع، فإن Microsoft لم ير مناسبا لتقديم هذه الوظائف منذ عشر سنوات، فماذا يكلفونهم أن يزعجهم فقط لأنهم في معيار IEEE754؟

تعديل: لاحظ أن Scalb و LOGB محددة في IEEE754-1985 الملحق "الوظائف الموصى بها وتتسم"، لكن التذييل قال صراحة "ليس جزءا من" المعيار.

إذا كنت تعرف أنك على نظام IEEE (وفي هذه الأيام، فأنت تفعل ذلك، فلا حاجة إلى هذه الوظائف: فقط فحص البتات مباشرة من خلال اتحاد ساعة مع uint64_t. يفترض أنك تستخدم هذه الوظائف باهتمام الكفاءة في المقام الأول (وإلا فسوف تستخدم عمليات طبيعية أكثر log() أو exp())، لذلك فإن قضاء القليل من الجهد على مطابقة التعليمات البرمجية الخاصة بك إلى تمثيل النقطة العائمة ربما جديرة بالاهتمام.

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