سؤال

لقد استخدمت دائمًا التدفقات أو printf أو السلسلة (x) أو أي اللغة المعروضة التي يتم تقديمها لتحويل أنواع الرقمية إلى سلسلة أو للخلف. ومع ذلك لم أفكر أبدًا في كيفية القيام بذلك بالفعل. لقد بحثت حول Google ، ولكن جميع النتائج هي فقط لاستخدام هذه الأساليب المتنوعة ، وليس كيف يتم التحويل بالفعل وراء الكواليس :(

بالنسبة للأعداد الصحيحة باستخدام الثنائي ، يبدو الثنائي أوكتال وسداسي عشوائيًا مستقيمًا إلى الأمام إلى حد ما لأن كل "رقم" في السلسلة يمثل مجموعة من البتات (على سبيل المثال لأرقام سداسية 2 أعرفها رقم في وقت واحد ، على سبيل المثال لسلسلة السداسي 0xfa20 ، القيمة هي "(15 << 12) | (10 << 8) | (2 << 4) | (0 << 0)".

الأعداد الصحيحة العشرية أكثر صعوبة لأن القاعدة 10 لا تخطط إلى قاعدة 2 من هذا القبيل ، وبالتالي قد تؤثر جزء واحد على أكثر من أرقام عشرية مما يجعل التحويل في كلا الاتجاهين أكثر تعقيدًا ...

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

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

المحلول

التحويلات العشرية أبطأ بعض الشيء ، ولكن ليس أكثر تعقيدًا. دعونا نلقي نظرة على تحويل سداسي عشري أشبه بقليل أننا ربما نكتبه في رمز حقيقي. على سبيل المثال فقط ، في C ++ ، يمكنك القيام بالتحويل شيئًا من هذا القبيل:

char digits[] = "0123456789abcdef";
std::string result;

int input = 0xFA20;

while (input) {
    int digit = input & 0xf; // or: digit = input % 0xf;
    input >>= 4;             // or: input /= 16;
    result.push_front(digits[digit]);
}

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

const int base = 16;

while (input) { 
    int digit = input % (base - 1);
    input /= base;
    result.push_front(digits[digit]);
}

في عملية التخلص من هذه الأرقام السحرية ، جعلنا أيضًا الروتين عالميًا تقريبًا - إذا قمنا بتغيير قيمة "القاعدة" ، فإن بقية الروتين لا يزال يعمل ، وتحويل المدخلات إلى القاعدة المحددة. في الأساس التغيير الآخر الوحيد الذي نحتاج إلى إجراؤه هو إضافة المزيد إلى صفيف "الأرقام" إذا أردنا دعم القواعد التي تزيد عن 16.

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

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

نصائح أخرى

لقد بحثت حول Google ، ولكن جميع النتائج هي فقط لاستخدام هذه الأساليب المتنوعة ، وليس كيف يتم التحويل بالفعل وراء الكواليس :(

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

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

بالنسبة للأعداد الصحيحة ، يمكنك العثور على بقية التقسيم ، وهذا هو الرقم الأخير ، ويقسم على 10 ، ووجدت Modular Metainial - هذا رقم واحد ولكن الأخير ، وهكذا. يتم إنشاء أرقام النقاط العائمة من جزأين - أرقام وهامة ، أي الرقم = مهم.

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