您的位置:首页 > 其它

itoa函数,考虑当待处理整数为-2^(字长-1)的情况

2011-05-25 15:52 274 查看
源自《The C Programming Language》 P53 pr3-4:

在数的对二的补码表示中,我们编写的itoa函数不能处理最大的负数,即n等于-(2^(字长-1))的情况。请解释原因,

修改函数使得它在任意机器上运行时都能得到正确结果。

代码:

#include <stdio.h>
#include <string.h>

#define		MAXLINE		100

void itoa(int n, char s[]);
void reverse(char s[]);

int main()
{

int num;
char res_str[MAXLINE];

num = -2147483648;
itoa(num, res_str);
printf("%s/n", res_str);

return 0;
}

void reverse(char s[])
{

int i, j;
char temp;

for(i = 0,j = strlen(s)-1; i < j; ++i,--j)	//注意:别写成j = strlen(s)了
{
temp = s[i];
s[i] = s[j];
s[j] = temp;
}

}

/*void itoa(int n, char s[])
{

int flag;
int i;

flag = 1;
i = 0;
if(n < 0)
{
n = -n;
flag = -1;
}
do
{
s[i++] = n % 10 + '0';
}while((n /= 10) > 0);
if(flag == -1)
s[i++] = '-';
s[i] = '/0';
reverse(s);

}
*/

/*********************************************************************
参考代码
*********************************************************************/

void itoa(int n, char s[])	//优点:可以处理-(2^(字长-1))这种情况
{
int sign;
int i;

sign = n;
i = 0;
do
{
s[i++] = abs(n % 10) + '0';
}while((n /= 10) != 0);	//不写成(n /= 10) > 0是考虑到n为负数的情况
if(sign < 0)
s[i++] = '-';
s[i] = '/0';
reverse(s);

}


分析:

1, 原因:对于整数的对二补码表示中,所能表示的最大整数值为2^(字长-1) - 1,故不能通过n = -n;

将-(2^(字长-1))转化为2^(字长-1),而是通过abs宏取绝对值的方法abs(n % 10)得到,

比如n = -2147483648(即-(2^(字长-1)),通过abs(n % 10)得到8,这样就绕过了上述

的问题。

2, 参考代码的重点:

(a):用abs(n % 10)而非n = -n来规避当n为最小整数(-2147483648)时。

(b):do-while循环的判断条件用((n / 10) != 0)而非((n / 10) > 0)来避免当n是个负数时

使itoa函数陷入无限循环汇总。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐