أفضل طريقة لتنفيذ BCD باعتبارها ممارسة الرياضة ؟

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

  •  19-08-2019
  •  | 
  •  

سؤال

أنا مبتدئ (التعلم الذاتي) مبرمج تعلم C++, ومؤخرا قررت لتنفيذ الثنائية مشفرة عشريا (BCD) الطبقة باعتبارها ممارسة ، حتى أتمكن من التعامل مع أعداد كبيرة جدا على المشروع يولر.أود أن تفعل ذلك كما في الأساس ممكن ، بدءا صحيح من الصفر.

لقد بدأت باستخدام مجموعة من رجات ، حيث كل رقم من عدد المدخلات تم حفظها منفصلة int.وأنا أعلم أن كل BCD أرقام يمكن المشفرة فقط 4 بت ، حتى ظننت باستخدام كله الباحث في هذا مبالغة بعض الشيء.أنا الآن باستخدام مجموعة من bitset<4>'s.

  1. هو باستخدام مكتبة فئة مثل هذا مبالغة ؟
  2. هل نعتبر ذلك خيانة ؟
  3. هل هناك طريقة أفضل للقيام بذلك ؟

تحرير:السبب الرئيسي في ذلك هو ممارسة لا ترغب في استخدام المكتبة مثل GMP لأن الهدف هو جعل الطبقة نفسي.هل هناك طريقة للتأكد من أن كنت تستخدم فقط 4 بت لكل أرقام عشرية?

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

المحلول

فقط ملاحظة واحدة ، باستخدام مجموعة من bitset<4>'ق سوف تتطلب نفس القدر من الفضاء مجموعة من لونغ.bitset عادة ما تنفذ من خلال وجود مجموعة من word الحجم الصحيحه يتم تخزين النسخ على البتات ، حيث أن جميع العمليات يمكن استخدام المعامل كلمة العمليات ، وليس بايت منها ، حتى يحصل على عمل المزيد في وقت واحد.

كما أنني السؤال الدافع الخاص بك.BCD وعادة ما يستخدم معبأة تمثيل سلسلة من الأرقام عند إرسالها بين النظم.ليس هناك حقا أي شيء للقيام مع الحساب عادة.ما كنت تريد حقا هو التعسفي الحجم صحيح مكتبة الحسابية مثل GMP.

نصائح أخرى

هو باستخدام مكتبة فئة مثل هذا مبالغة ؟

أود أن المعيار هو ضد مجموعة من رجات لمعرفة أي واحد هو الأفضل.إذا مجموعة من bitset<4> هو أسرع ثم لا انها ليست مبالغة.كل قليلا يساعد على بعض PE مشاكل

هل نعتبر ذلك خيانة ؟

لا على الإطلاق.

هل هناك طريقة أفضل للقيام بذلك ؟

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

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

إذا كنت ترغب في استخدام معبأة BCD ، يمكن أن تكتب مخصص الفهرسة وظيفة تخزين رقمين في كل بايت.

  1. هو باستخدام مكتبة فئة مثل هذا مبالغة ؟
  2. هل نعتبر ذلك خيانة ؟
  3. هل هناك طريقة أفضل للقيام بذلك ؟

1&2:لا حقا

3:كل بايت حصلت 8-بت, هل يمكن تخزين 2 BCD في كل char غير الموقعة.

في عام ، بت العمليات يتم تطبيقها في سياق صحيح ، حتى من جانب الأداء لا يوجد سبب حقيقي للذهاب إلى بت.

إذا كنت تريد أن تذهب إلى بت نهج لاكتساب الخبرة ، ثم قد يكون هذا مساعدة

#include <stdio.h>
int main
(
    void
)
{
    typedef struct
    {
        unsigned int value:4;

    } Nibble;

    Nibble nibble;

    for (nibble.value = 0; nibble.value < 20; nibble.value++)
    {
        printf("nibble.value is %d\n", nibble.value);
    }

    return 0;
}

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

ويظهر هذا بوضوح من قبل بالنسبة حلقة ، الذي هو في الواقع حلقة لانهائية.عندما عاب قيمة يضرب, 16, القيمة صفر حقا ، كما أن هناك فقط 4 بت للعمل مع.نتيجة عاب.القيمة < 20 لم يصبح صحيحا.

إذا كنت تبحث في K&R الكتاب الأبيض ، واحدة من الملاحظات هناك حقيقة أن بعض العمليات مثل هذه ليس المحمولة, لذا إذا كنت ترغب في المنفذ الخاص بك البرنامج إلى منصة أخرى ، قد أو قد لا تعمل.

يكون متعة.

كنت تحاول الحصول على قاعدة-10 تمثيل (أيأرقام عشرية في كل خلية في المصفوفة).هذه الطريقة إما الفضاء (كثافة واحدة في أرقام) أو الوقت (4-بت في dgit ، ولكن هناك أحمال من التعبئة/الفتح) يضيع.

لماذا لا نحاول مع قاعدة-256 ، على سبيل المثال ، استخدام صفيف من البايت?أو حتى قاعدة-2^32 مع مجموعة من رجات?عمليات يتم تنفيذها في نفس الطريقة كما في الأساس 10.الشيء الوحيد الذي سوف تكون مختلفة هو تحويل رقم إلى الإنسان للقراءة السلسلة.

قد تعمل مثل هذا:على افتراض قاعدة-256 ، كل "رقم" 256 القيم الممكنة ، حتى الأرقام 0-255 كل واحد أرقام القيم.من 256 كما هو مكتوب 1:0 (سوف تستخدم القولون فصل "أرقام" لا يمكننا استخدام الحروف في قاعدة-16), analoge في قاعدة-10 كم على بعد 9 ، 10.وبالمثل 1030 (قاعدة-10) = 4 * 256 + 6 = 4:6 (قاعدة-256).أيضا 1020 (قاعدة-10) = 3 * 256 + 252 = 3:252 (قاعدة-256) هو عدد من رقمين في قاعدة-256.

الآن دعونا نفترض وضعنا الأرقام في مجموعة من بايت مع رقم كبير على الأقل الأولى:

unsigned short digits1[] = { 212, 121 }; // 121 * 256 + 212 = 31188
int len1 = 2;
unsigned short digits2[] = { 202, 20  }; // 20 * 256 + 202 = 5322
int len2 = 2;

ثم إضافة يذهب مثل هذا (تحذير:المفكرة رمز المقبلة ، قد تكون مكسورة):

unsigned short resultdigits[enough length] = { 0 };
int len = len1 > len2 ? len1 : len2; // max of the lengths
int carry = 0;
int i;
for (i = 0; i < len; i++) {
    int leftdigit = i < len1 ? digits1[i] : 0;
    int rightdigit = i < len2 ? digits2[i] : 0;
    int sum = leftdigit + rightdigit + carry;
    if (sum > 255) {
        carry = 1;
        sum -= 256;
    } else {
        carry = 0;
    }
    resultdigits[i] = sum;
}
if (carry > 0) {
    resultdigits[i] = carry;
}

على التكرار الأول أنه ينبغي أن يذهب مثل هذا:

  1. المبلغ = 212 + 202 + 0 = 414
  2. 414 > 256 ، وحمل = 1 المجموع = 414 - 256 = 158
  3. resultdigits[0] = 158

على التكرار الثاني:

  1. المبلغ = 121 + 20 + 1 = 142
  2. 142 < 256, لذلك حمل = 0
  3. resultdigits[1] = 142

حتى في نهاية resultdigits[] = { 158, 142 }, وهذا هو 142:158 (قاعدة-256) = 142 * 256 + 158 = 36510 (قاعدة-10) ، وهو بالضبط 31188 + 5322

علما أن تحويل هذا الرقم إلى/من الإنسان شكل مقروء ليست مهمة تافهة - أنه يتطلب الضرب والقسمة قبل 10 أو 256 و لا يمكنني أن هذا القانون كعينة دون البحث السليم.ميزة هي أن عمليات 'إضافة', 'طرح' و 'ضرب' يمكن أن تكون فعالة حقا الثقيلة التحويل من قاعدة-10 يتم مرة واحدة فقط في بداية ومرة بعد نهاية الحساب.

وبعد كل ذلك, شخصيا, كنت استخدم قاعدة 10 في صفيف من البايت و لا يهتمون فقدان الذاكرة.وهذا يتطلب ضبط الثوابت 255 و 256 أعلاه إلى 9 و 10 على التوالي.

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