كيف يمكنني استخراج الأرقام بأمان وبسرعة من int؟
سؤال
لدينا حاليًا بعض التعليمات البرمجية لاستخراج الأرقام من 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;
}