3

我们目前有一些代码可以从 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 字符串是因为速度非常重要。

4

5 回答 5

7

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数字的十倍,加上第一个数字。

我怀疑速度可能比你现在得到的更好,但这当然取决于你在你的特定平台和编译器上衡量。

于 2010-08-31T04:22:25.027 回答
2

使用sprintf应该没问题。sizeof type * 3 * CHAR_BIT / 8 + 2是一个足够大的缓冲区,用于打印类型为 的整数type。如果假设CHAR_BIT为 8 或只关心无符号格式,则可以简化此表达式。它背后的基本思想是每个字节在十进制(或八进制)中最多贡献 3 位数字,并且您需要空间用于符号和空终止。

于 2010-08-31T04:28:38.010 回答
1

到目前为止,有一个交换最后两位数字的答案和一个交换前两位数字的答案……在我看来,它"%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
于 2010-08-31T04:49:43.423 回答
0

也应该适用于 0 和 <0。

int extract_op( int instruction )
{
  int numd = 1;
  while( instruction /= 10 )
    ++numd;
  return numd;
}
于 2010-08-31T05:05:31.133 回答
0

你可以存储你进入数组的数字。这是 ALEX 解释的代码。在这里,我添加了一些变量。

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 位数。但是如果你想采用动态数组,那么你可以使用链接列表

于 2010-08-31T04:56:30.013 回答