首页
社区
课程
招聘
C语言itoa函数处理最小负数的问题
发表于: 2014-3-6 11:32 6808

C语言itoa函数处理最小负数的问题

2014-3-6 11:32
6808
《C程序设计语言》中itoa函数示例代码:



《C程序设计语言》第53页练习3-4:在数的对二代补码中,我们编写的itoa函数不能处理最大的负数(应该是“最小的负数吧”。。。不过书上是这么写的),即n等于-(2^(字长-1))的情况,请解释其原因。修改该函数,使它在任何机器上运行时都能打印出正确的值。

首先做一个实验,处理-(2^(字长-1))+1,可以得出正确结果:


再处理-(2^(字长-1)),将(2)处代码的数值改为-2147483648,出现编译警告并得不出正确结果:

-(2^(字长-1))这个值取相反数后的补码与原数的补码相同,因此itoa函数无法处理出正确结果。

对于问题的第二问,我想到了将n强制转换为unsigned int类型。将(1)处代码改为:n = (unsigned int)n;结果还是产生编译警告:


不知道这是为什么,怎么解决?求教。

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
写的很清楚了啊。 你写的这个数值。超过了int 表示的范围了。   

第二次的警告是因为unsigned 只能表示 正数。你给了个负数。
2014-3-6 12:17
0
雪    币: 20923
活跃值: (4120)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
void itoa(int n,char s[])
{
        int i,sign;
        unsigned int un; // <===== add unsigned int un

        if ((sign=n)<0)
                un=(unsigned int)n;  // <=== change n to un
        i=0;
        do
        {
                s[i++]= un % 10 + '0';  // <=== change n to un
        } while ((un /-10)>0); // <=== change n to un

       .....
      ....

int range : -2147483648 to 2147483647
你可以试一试。
2014-3-6 12:24
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
[QUOTE=atompure;1265930]void itoa(int n,char s[])
{
        int i,sign;
        unsigned int un; // <===== add unsigned int un

        if ((sign=n)<0)
                un=(unsigned int)n;  // <=== change n to ...[/QUOTE]

按照您指教的,果然能得出正确结果,我想了想,应该是不能把unsigned int类型数据((unsigned int)n)赋值给int类型数(n)据引起的警告,所以又验证了一下,不过问题又出来了:


按照我自己的想法,将long型赋值给int类型应该也会产生编译警告才对。
再看了看itoa程序:


编译警告的实际上并不是语句n = (unsigned int)n;而是语句int i = -2147483648;引起的,这我就更不明白了,如果n = -2147483648,那么前者应该产生“warning:assignment to 'int' from 'unsigned int'”才对,而不是后者有"warning:decimal constant is so large that is unsigned"才对啊。

再次请教您了。
上传的附件:
2014-3-6 21:10
0
雪    币: 20923
活跃值: (4120)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
unsigned int range : 0 to 4294967295
int range : -2147483648 to 2147483647
int n;
n=-2147483648;
n = (unsigned int)n;  // <== (unsigned int) n equals +2147483648 (no minus)
                                 // but 左边n is declared int, n = +2147483648 .... exceeds 2147483647 !!!
我是这样理解。
不知道,对不对。。
我是用visual c 2008 没有warning.
2014-3-7 06:39
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
嗯,我也是这么想的。我用的是C-Free,看来我可以用“问题来自于编译器”来自慰了。。。

非常感谢您的指教!
2014-3-7 11:39
0
游客
登录 | 注册 方可回帖
返回
//