zoukankan      html  css  js  c++  java
  • 有符号的范围,-128~+127详解(zt)

    这是一个困惑了我几年的问题,它让我对现在的教科书和老师极其不满,从我N年前开始摸电脑时,就几乎在每一本C++教科书上都说,8位有符号的取值范围是-128~+127,为什么不是-127~+127呢,后来的java,int的聚值范围,再32位计算,-2^31 ~ +2^31-1,可是,却从来没有任何一本教科书或一个老师比我解释过这个问题 
    原因没有在工作上或者是什么地方直接遇到它,所以我也一直忽略它,但心里总是有一根刺.直到刚才!!!! 
    就是刚才,无聊之极,在看汇编的书时,又遇到它了,但一如以往,书上直接地,有心地,明显地绕过了这个问题,真是可恶啊 
    几经周折,终于把它搞清楚了: 
    其实,它是计算机底层为了实现数值运算而决定的,涉及非常非常基础的原码,反码,补码知识,一般(99.9999%)都不会用得上. 
    那0.0001%,估计也就是计算机考试了, 
    话说: 
    用2^8来表示无符号整数的话,全世界的理解都是0 - 255了,那么,有符号呢? 用最高位表示符号,0为+,1为-,那么,正常的理解就是 -127 至 +127 了. 
    这就是原码了,值得一提的是,原码的弱点,有2个0,即+0和-0,还有就是,进行异号相加或同号相减时,比较笨蛋,先要判断2个数的绝对值大小,然后进行加减操作,最后运算结果的符号还要与大的符号相同. 
    于是乎,反码产生了,原因....略,反正,没过多久,反码就成为了过滤产物,也就是,后来补码出现了. 
    补码的知识不说述,只说有关+127和-128的. 
    官方的定义 [-2^(n-1),2(n-1)-1],补码的0没有正负之分 
    原因呢?没有一本书上有说,这也是我这么火的原因,但通过思考,google,再思考,很快找到答案: 
    首先,难不免干点白痴般地事情,穷举一下... 
    正数,原码跟补码一样 
    +127, 0111 1111 
    +126, 0111 1110 
    +125, 0111 1101 
    +124, 0111 1100 
    +123, 0111 1011 
    +122, 0111 1010 
    ... 
      +4, 0000 0100 
      +3, 0000 0011 
      +2, 0000 0010 
      +1, 0000 0001 
       0, 0000 0000 (无正负之分) 

    下面是负数了,值,原码,符号位不变其它取反,+1 

      -1, 1000 0001, 1111 1110, 1111 1111 
      -2, 1000 0010, 1111 1101, 1111 1110 
      -3, 1000 0011, 1111 1100, 1111 1101 
      -4, 1000 0100, 1111 1011, 1111 1100 
      -5, 1000 0101, 1111 1010, 1111 1011 
      -6, 1000 0110, 1111 1001, 1111 1010 
      -7, 1000 0111, 1111 1000, 1111 1001 
      -8, 1000 1000, 1111 0111, 1111 1000 
      -9, 1000 1001, 1111 0110, 1111 0111 
    -10, 1000 1010, 1111 0101, 1111 0110 
    -11, 1000 1011, 1111 0100, 1111 0101 
    -12, 1000 1100, 1111 0011, 1111 0100 
    -13, 1000 1101, 1111 0010, 1111 0011 
    -14, 1000 1110, 1111 0001, 1111 0010 
    -15, 1000 1111, 1111 0000, 1111 0001 
    -16, 1001 0000, 1110 1111, 1111 0000 
    -17, 1001 0001, 1110 1110, 1110 1111 
    ... 
    -24, 1001 1000, 1110 0111, 1110 1000 
    ... 
    -99, 1110 0011, 1001 1100, 1110 0100 
    ... 
    -124, 1111 1100, 1000 0011, 1111 1101 
    -125, 1111 1101, 1000 0010, 1000 0011 
    -126, 1111 1110, 1000 0001, 1000 0010 
    -127, 1111 1111, 1000 0000, 1000 0001 
    看出点什么了没有? 
    如果没有,那么,给个提示, 再继续下去,下一个补码是什么呢? 

    当然是 
    -128, 先略过,再略过, 1000 0000 

    1000 0000,那么,它的原码是什么呢? 
    从补码求原码的方法跟原码求补码是一样的 
    先保留符号位其它求反:  1111 1111, 再加1:11000 0000, 超过了8位了 
    对,用8位数的原码在这里已经无法表示了 
    关键就在这里,补码 1000 0000 为 -128 是不用怀疑的(上面的穷举), 
    那么,回到原码处, 它的原码也是 1000 0000(超出的自动丢失), 
    1000 0000 在原码表示什么呢? -0, 但补码却规定0没有正负之分 
    转换一下思路,看看计算机里,是怎么运算的: 
    对于负数,先取绝对值,然后求反,加一 
    -128 -> 128 -> 1000 0000 -> 0111 1111 -> 1000 0000 
    现在明确了吧 
    所以, 8位有符号的整数取值范围的补码表示 
    1000 0000 到 0000 0000, 再到 0111 1111 
    即 -128 到 0, 再到 127 
    最终 -128 ~ +127 
    感谢google,感谢被我浏览过又关闭了还忘记了姓名的广大的blog们,CSDN(那上面也有些不错的东西) 
    over~

  • 相关阅读:
    完美解决CTRL+空格不能切换中/英文输入法的问题
    【Delphi内联汇编学习1】Delphi与汇编
    替换bmp图片中的颜色 good
    将四个BYTE数值转换成IEEE754标准的浮点数(两种方法:用Addr函数取字节数字的首地址,或者用Absolute关键字)
    在delphi的exe文件中嵌入另外一个exe文件
    Qt中的串口编程之三
    使用MIDAS访问远程Access数据库
    QSqlDatabase的进一步封装(多线程支持+更加简单的操作)——同时支持MySQL, SQL Server和Sqlite
    Qt for Linux:环境搭建(CentOS 6.5 32位)——完全从零安装
    Qt for Windows:使用WinPcap开发高性能UDP服务器
  • 原文地址:https://www.cnblogs.com/bluewelkin/p/3328635.html
Copyright © 2011-2022 走看看