The C Programming Language 练习题3-4

题目
在数的对二的补码表示中,我们编写的itoa函数不能处理最大的负数,即n等于-2 ^(字长-1)的情况。请解释其原因。修改该函数,使它在任何机器上运行时都能打印出正确的值。

题目分析
因为在计算机中,负数的存储是以补码形式存放。所以本机最大负数-2147483648存储形式是(1000 0000 0000 0000 0000 0000 0000 0000‬),所以理论上原代码中”n = -n”这个运算就会导致结果为0。(实际上并不是,我观察了下,如果n等于最大负数,n=-n的结果是n仍然等于最大负数。在电脑上也试了下,确实如果输入是1000……,那么加负号仍然不变。应该是溢出导致的吧。因为一个有符号数的最大正值在计算机中存储方式是第一位符号位0,然后后面都是1,而最大负数的绝对值要比最大正数还大1——所以没办法表示了。)
要解决这个问题,得先把这个负数变成无符号数再做处理。

代码实现

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

void reverse(char s[])
{
    int c, i, j;
    for (i = 0, j = strlen(s)-1; i < j; i++, j--)
        {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
        }
}

void itoa(int n, char s[])
{
    int i, sign;
    unsigned m;

    if ((sign = n) < 0) /* record sign */
        m = -n; /* make n positive */
    i = 0;

    do
        { /* generate digits in reverse order */
        s[i++] = m % 10 + '0'; /* get next digit */
        }
    while ((m /= 10) > 0); /* delete it */

    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    reverse(s);
}

int main()
{
    int i, n;
    char s1[20] ;

    i = -2147483648;
    itoa(i, s1);
    n = 0;
    while (s1[n] != '\0')
        printf("%c", s1[n++]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值