有符号与无符号

个人资料
迪斌仔
迪斌仔
博客十周年
博客十周年地图
  • 博客等级:
  • 博客积分:469积分
  • 博客访问:46,848
  • 关注人气:18
  • 获赠金笔:5
  • 赠出金笔:0
  • 荣誉徽章:点亮荣誉勋章兑换图片博主服务兑换私密博文兑换金笔
谁看过这篇博文
正文 字体大小:  

细谈有符号与无符号数的区别(一)

  (2012-02-21 11:02:34)
标签: 

it

分类: 编程语言

 #include<stdio.h>
int main()
{
unsigned int a=32;
int b=-6;
unsigned int c=a+b;
printf("%u",c);

}
无意看到以上代码,发现自己也是一知半解的,这才决定弄透一点。
以下均为自己对网上资料的理解,希望对大家能有所帮助,有误之处,还请海涵。
首先列举下数据类型:(signed )int ,unsigned int ,float ,double ,char

注意点

1.声明无符号整型时,我们都加上unsigned int ,而声明有符号整型时用signed int,
我们平常直接写int,省掉了signed.
另外,unsigned若省略后一个关键字,大多数编译器都会认为是unsigned int。

2.在计算机中,整数是以补码形式存放的
只是带符号的整数采用补码存储表示的,浮点数另有其存储方式)。
 
 3.无符号数没有原码、反码和补码一说。只有带符号数才存在不同的编码方式。

4.整形数运算,总是遵循一个原则:小的往大的扩展
从小到大:short -> unsigned short -> int -> unsigned int  


下面说说各数据类型值的范围
(32 bit Operate System,通过开始——运行,输入DXDIAG 命令即可查到自己电脑系统位数):

         (signed) int   :  -2^31 ~ 2^31-1(-2147483648 ~ 2147483647)
         unsigned int  :    0 ~ 2^32-1   (0 ~ 4294967295)


既然只对signed int 才有所谓的原码、反码和补码,那我们就对signed int 来分析,
   码制转换规则:当 变量(前提是有符号整型)是非负数时,
                                         其原码、反码和补码表示都是一样的。

                               当变量是负数时,其反码是对原码的除符号位外的其他位进行取反后的结果
                    (取反即如果该位为
0则变为1,而该位为1则变为0的操作)。

                而补码是先求原码的反码,
                然后在反码的末尾位加
后得到的结果,即补码是反码+1
        例如:int a =32,其原码为0x00000020,反码、补码均如此

        例如:int a =32,其原码为0x00000020,反码、补码均如此

              int A=-6,其原码为1000 0000 0000 0000 0000 0000 0000 0110
                       (开头的1为符号位),即为0x80000006,

                反码即为0xFFFFFFF9,补码即为0xFFFFFFFa(在反码基础上再加1).
 

注意点
1.码制转换后的数就应该理解成无符号型的了,不然只对有符号型整数转换干嘛
             (即码制转换应用于无符号与有符号之间 的转换问题上)。

 2.要将计算机输出的数值和我们所常用的数值区分开来。
         例如:-(2^31-1)在%u下输出2147483649,该值大于2^31-1(但它不是int 下的值),
               就不要被上面的取值范围给搞迷惑了。

3.符号位也是要占地方的。假如一个8位的系统,a=-6,其原码就该写成1000 0110,
        若写成1 0000 0110,就很让人费解,似乎符号位不占空间似的,
        个人觉得这种写法不合理的,
而且我这种写法更有利于理解值的范围。
 例如:上面提过int 范围值为 -2^31 ~ 2^31-1,若按我的理解,
        就是int 32位里第一位拿来做符号位,
当其为正数时,最大值为31个1,即2^31-1,
          当其为负数时,数值部分也是31个1,那最小值应该
是-(2^31-1),
    为何与上面不一致呢?

         别忘了,开始就说过,计算机存储有符号整数是采用补码形式的。
         即最小值对应的补码是0x80000001,即为2147483649,不信你可以运行试试。
         那最小值-2^31是怎么来的?待会儿再想。


   现在再来解释一下上面的小题目,也就容易了:
                   unsigned int a=32,其二进制编码为0x00000020
                        (为了简便,这里用十六进制hexadecimal  ['heksəˌdesiməl]表示)
                    int b=-6,如上已经算出补码0xFFFFFFFa,
                    a和b相加,按注意点里第4项看,都往unsigned int 转换。

                   二进制相加可得0x0000001a(溢出位去掉),即为26,其为正数,
                   所以输出%d,%u格式不会影响结果。


  仔细调试该小题,可得如下结果:
                   1.unsigned int 变量的值可以直接看成int 型里的正值,
                      所以上面小题就可以直接看成int型的加减法。

                       当输出结果为正值时,输出格式%d,%u都一样,负值当然就不一样了。
                   2.如果c为int型,则输出结果要满足是在int型值范围内,
                       不然可以依然应用 "结果1"法则。

                       若a=2147483649,b=-1,结果超出最大值2147483647。
                       输出格式为%u时,计算向平常的一样,
                     输出格式为%d时,明显超过了值的范围,电脑会怎么输出,
                       本人从运行结果看不出头绪。
大家知道的,可以说说结果-2147483648是如何来的?

0

0

阅读 (480)   评论  (1) 收藏 (0)  转载 (0)   喜欢   打印 举报
已投稿到:
  • BigHead


    回答博主的问题:
    int c 最后存放的数据为0x80000000,
    作为有符号数:2147483648,很显然的。
    作为无符号的int:-2147483648,这个数并没有超过界限,
    int所能表示的数据范围在:-2147483648 ~ 2147483647。

    2012-5-28  18:11回复(0)

发评论
id="postCommentIframe" frameborder="0" src="http://blog.sina.com.cn/main_v5/ria/blank2.html" style="border: 1px solid rgb(199, 199, 199); height: 158px; width: 448px;">
  • 灌水
  • 赞
  • 美好
  • 顶
  • 顶
  • 顶
  • 开心
  • 路过

登录名: 密码: 找回密码 注册

    

>>> 拖动滑块完成验证 >>>

发评论

以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

新浪BLOG意见反馈留言板 不良信息反馈 电话:4006900000 提示音后按1键(按当地市话标准计费) 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

新浪公司 版权所有

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值