C程序设计语言 3-4

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

错误在于补码表示中正数取值范围比复数小一。补码的表示即为模运算表示法。举个简单的例子,假如计算机表示的位数为3位,即000~111,如果不要求表示负数,那么000~111换算成十进制即为0~7,即计算机只能表示0~7,这就是unsigned int。然而如果要求表示负数的话,那么这三位中有一位需要作为符号位存在。所以最终表示分别为:000:0,001:1, 010:2,011:3,100:-4,101:-3,110:-2,111:-1同样可以表示8个数,但是由于0的存在,所以正数和负数的数量不相等。再举一个例子加深理解(来自百度百科):

 

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

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

int main()
{
	int n = (~0U >> 1) + 1;
	char s[10];
	itoa_2(n, s);
	printf("s:%s\n", s);
	
	return 0;
}

void itoa_2(int n, char s[])
{
	int i, sign;

	sign = n;
	i = 0;
	do {
		if (sign < 0)
			s[i++] = -(n % 10) + '0';
		else 
			s[i++] = n % 10 + '0';
	} while ((n /= 10) != 0);
	if (sign < 0)
		s[i++] = '-';
	s[i] = '\0';
	reverse(s);
	
	return;
}

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;
	}
	return;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值