كيف يمكنني استخراج الأرقام بأمان وبسرعة من int؟

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

  •  25-09-2019
  •  | 
  •  

سؤال

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

int extract_op(int instruction)
{ 
    char buffer[OP_LEN+1];
    snprintf(buffer, sizeof(buffer), "%0*u", OP_LEN, instruction);
    return (buffer[1] - 48) * 10 + buffer[0] - 48;
}

نحن نستخدم سلاسل C لأن السرعة مهمة للغاية.

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

المحلول

استخدام sprintf يجب ان يكون بخير. sizeof type * 3 * CHAR_BIT / 8 + 2 هو مخزن مؤقت كبير بما فيه الكفاية لطباعة عدد صحيح من النوع type. يمكنك تبسيط هذا التعبير إذا افترضت CHAR_BIT هو 8 أو إذا كنت تهتم فقط بالتنسيقات غير الموقعة. الفكرة الأساسية وراء ذلك هي أن كل بايت يساهم في أكثر من 3 أرقام في عشري (أو ثماني) ، وتحتاج إلى مساحة لعلامة وإنهاء فارغ.

نصائح أخرى

لا تحتاج إلى التكوين instruction في مجموعة شخصية لهذا الغرض ؛ تحتاج فقط إلى الاحتفاظ بـ "الرقمين الأعلى" ، على النحو التالي:

int extract_op(unsigned int instruction)
{
    int first = 0;
    int second = 0;
    while(instruction) {
        second = first;
        first = instruction % 10;
        instruction /= 10;
    }
    return first + 10 * second;
}

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

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

حتى الآن ، هناك إجابة واحدة تبادل في آخر رقمين وواحد يتبادل الأولين ... يبدو لي مثل "%0*u", OP_LEN هو إجبار الإخراج على عرض معين ، وأهمية الأرقام المستخرجة محددة مسبقا بواسطة OP_LEN.

على افتراض OP_LEN هو ماكرو ، يمكننا الحصول على 10^(op_len-2) مع

#define DIVISOR ( (int) ( 1.e ## OP_LEN * 0.01 ) )

ثم ، على غرار إجابة @Zneak ،

int extract_op( int instruction )
{
    instruction /= DIVISOR;
    int tens = (instruction / 10) % 10;
    int units = instruction % 10;
    return units * 10 + tens;
}

#undef DIVISOR

يمكنك تخزين الرقم الذي تدخل في صفيف. كان هذا هو الرمز الذي أوضحه أليكس. أنا هنا أضيف بعض المتغيرات.

int a[5];

int extract_op(unsigned int instruction)
{
int i=0;    
int first = 0;
    int second = 0;
    while(instruction) {
        second = first;
        first = instruction % 10;
        instruction /= 10;
    }
    a[i]=first;
}

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

يجب أن تعمل أيضا من أجل 0 و <0.

int extract_op( int instruction )
{
  int numd = 1;
  while( instruction /= 10 )
    ++numd;
  return numd;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top