سؤال

لدي 3 قاعدة التمثيل الإيجابي أرقام صحيحة:

  1. عشري في موقعة طويلة متغير (مثل موقعة طويلة الباحث NumDec = 200).
  2. عرافة في متغير سلسلة (على سبيل المثال سلسلة NumHex = "C8")
  3. الثنائية في متغير سلسلة (على سبيل المثال سلسلة NumBin = "11001000")

كنت تريد أن تكون قادرة على تحويل بين الأرقام في 3 احتجاجات في الطريقة الأكثر فعالية.أولا-هاء.لتنفيذ التالية 6 وظائف:

unsigned long int Binary2Dec(const string & Bin) {}
unsigned long int Hex2Dec(const string & Hex) {}
string Dec2Hex(unsigned long int Dec) {}
string Binary2Hex(const string & Bin) {}
string Dec2Binary(unsigned long int Dec) {}
string Hex2Binary(const string & Hex) {}

ما هو النهج الأكثر فعالية لكل منهم ؟ يمكنني استخدام C و C++ ، ولكن ليس دفعة.

تحرير:من "الكفاءة" أعني وقت الكفاءة:أقصر وقت التنفيذ.

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

المحلول

كما أشار آخرون ، وأود أن تبدأ مع sscanf(), printf() و/أو strtoul().فهي سريعة بما فيه الكفاية بالنسبة لمعظم التطبيقات ، هم أقل احتمالا أن يكون الخلل.أقول ذلك أن هذه الوظائف هي أكثر عمومية مما قد تتوقع ، كما أنها تضطر إلى التعامل مع غير ASCII مجموعات الأحرف مع الأرقام تمثل في أي قاعدة دواليك.بالنسبة لبعض المجالات فمن الممكن للتغلب على وظائف المكتبة.

لذا قياس الأولى, و إذا كان أداء التحويل هذه هي حقا مسألة ، ثم:

1) في بعض التطبيقات / نطاقات أرقام معينة تظهر في كثير من الأحيان ، على سبيل المثال صفر, 100, 200, 19.95, قد تكون شائعة جدا أنه من المنطقي أن تحسين وظائف لتحويل هذه الأرقام مع مجموعة من إذا() البيانات ، ثم تعود مرة أخرى إلى عامة وظائف المكتبة.2) استخدام طاولة البحث إذا كان الأكثر شيوعا 100 أرقام ثم تقع مرة أخرى على وظيفة المكتبة.تذكر أن جداول كبيرة قد لا يصلح في ذاكرة التخزين المؤقت الخاصة بك قد تتطلب عدة indirections للمكتبات المشتركة ، وبالتالي تدبير هذه الأمور بعناية للتأكد من أنك لا يتناقص الأداء.

قد تحتاج أيضا إلى النظر في تعزيز lexical_cast الوظائف ، على الرغم من أن في تجربتي الأخيرة نسبيا مقارنة جيدة القديمة ج وظائف.

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

نصائح أخرى

أود أن أقترح فقط باستخدام sprintf و sscanf.

أيضا, إذا كنت مهتما في كيفية تنفيذه يمكنك أن تأخذ نظرة على التعليمات البرمجية المصدر بالنسبة سي العمومية ، GNU C المكتبة.

لماذا هذه الإجراءات يجب أن يكون ذلك الوقت-كفاءة ؟ هذا النوع من المطالبة دائما يجعلني أتساءل.هل أنت متأكد من الواضح أساليب التحويل مثل strtol() بطيئة جدا أو أنك يمكن أن نفعل ما هو أفضل ؟ نظام الوظائف عادة ما تكون فعالة جدا.فهي في بعض الأحيان أبطأ لدعم عمومية و تدقيق الأخطاء, ولكن تحتاج إلى النظر في ما يجب القيام به مع الأخطاء.إذا bin الحجة الشخصيات الأخرى من '0' و '1' ، ثم ماذا ؟ إلغاء المهمة ؟ نشر ضخمة الأخطاء ؟

لماذا تستخدم "ديسمبر" لتمثيل الداخلية التمثيل ؟ ديسمبر, Hex و Bin ينبغي أن تستخدم للإشارة إلى سلسلة احتجاجات.لا يوجد شيء عشري عن unsigned long.أنت تتعامل مع السلاسل عرض عدد عشري?إذا لا, أنت تخلط بين الناس هنا و سوف تخلط بين الكثير.

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

ذلك يعتمد على ما كنت تحسين ماذا تقصد ب "كفاءة"?من المهم أن التحويلات تكون سريعة واستخدام الذاكرة قليلا, قليلا مبرمج وقت أقل WTFs عن غيرها من المبرمجين قراءة رمز أو ماذا ؟

من أجل قراءة سهولة التنفيذ ، يجب أن ينفذ على الأقل على حد سواء Dec2Hex() و Dec2Binary() فقط عن طريق الدعوة strotul().أن يجعلها في أحد المتشددين, التي هي فعالة على الأقل بعض من سبق في تفسير كلمة.

يبدو كثيرا مثل الواجبات المنزلية المشكلة ، ولكن ما هيك...

الجواب القصير هو تحويل من الباحث إلى سلاسل الخاص بك استخدام اثنين من جداول البحث.ويجب أن يكون لكل جدول 256 الإدخالات.أحد الخرائط بايت إلى hex string:0 -> "00", 1 -> "01", الخ.آخر خرائط بايت إلى بت سلسلة:0 -> "00000000", 1 -> "00000001".

ثم لكل بايت في طويلة الباحث لديك فقط للبحث في السلسلة الصحيحة ، سلسلة لهم.

لتحويل من السلاسل مرة أخرى لفترة طويلة يمكنك ببساطة تحويل hex string و بت السلسلة إلى عدد عشري بضرب قيمة رقمية لكل حرف الطاقة المناسبة من 16 أو 2 ، وتلخيص النتائج.

تحرير:يمكنك أيضا استخدام نفس جداول البحث بالنسبة إلى الوراء التحويل عن طريق القيام الثنائية البحث عن الحق في السلسلة.هذا من شأنه أن سجل(256) = 8 مقارنات من سلاسل الخاص بك.للأسف ليس لدي الوقت للقيام تحليل ما إذا كانت المقارنة بين السلاسل سيكون أسرع بكثير من ضرب و إضافة الاعداد الصحيحه.

دعونا نفكر في نصف المهمة للحظة - تحويل من سلسلة أوتوماتيكية قاعدة n إلى غير موقعة طويلة, حيث n هو قوة 2 (قاعدة 2 ثنائي القاعدة 16 عرافة).

إذا كان رأيك هو عاقل ، ثم هذا العمل هو شيء أكثر من مجرد مقارنة ، subract ، والتحول ، أو في أرقام.إذا المدخلات الخاصة بك هو غير عاقل, حسنا, هذا هو المكان الذي تحصل عليه القبيح ، أليس كذلك ؟ القيام التحويل فائق السرعة ليس من الصعب.القيام بذلك بشكل جيد في جميع الظروف هو التحدي.

لذلك دعونا نفترض أن المدخلات الخاصة بك هو عاقل ، ثم قلب التحويل هو:

unsigned long PowerOfTwoFromString(char *input, int shift)
{
    unsigned long val = 0;
    char upperLimit = 'a' + (1 << shift)
    while (*input) {
        char c = tolower(*input++);
        unsigned long digit = (c > 'a' && c < upperLimit) ? c - 'a' + 10 : c - '0';
        val = (val << shift) | digit;
    }
    return val;
 }

 #define UlongFromBinaryString(str) PowerOfTwoFromString(str, 1)
 #define UlongFromHexString(str) PowerOfTwoFromString(str, 4)

انظر كم هو سهل ؟ وسوف تفشل على غير عاقل المدخلات.معظم العمل الخاص بك هو الذهاب إلى جعل المدخلات الخاصة بك عاقل وليس الأداء.

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

val = (val * base) + digit

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

لماذا لا مجرد استخدام ماكرو أيضا أن تأخذ شكل كمدخل.إذا كنت في C على الأقل.

#define TO_STRING( string, format, data) \
sprintf( string, "##format##", data)
// Int
TO_STRING(buf,%d,i);
// Hex ( Two char representation )
TO_STRING(buf,%02x,i);
// Binary
TO_STRING(buf,%b,i);

أو يمكنك استخدام sprintf مباشرة:أو هل يمكن أن يكون متعددة macroes.

#define INT_STRING( buf, data) \
sprintf( buf, "%d", data)
#define HEX_STRING( buf, data) \
sprintf( buf, "%x", data)
#define BIN_TO_STRING( buf, data) \
sprintf( buf, "%b", data)

BIN_TO_STRING( loc_buf, my_bin );
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top