zoukankan      html  css  js  c++  java
  • 整数的无符号编码和有符号编码

    单个的位没有实际意义,加上解释才有实际意义.我们可以把位组合在一起,并且加上解释以此赋予它意义.

    无符号编码表示的数 x >= 0

    有符号编码表示的数   min  <= x  and x <= max

    当我们对数字的运算超出编码所能表示的范围就叫做溢出.

    大多数计算机使用8位的块(字节)作为最小的可寻址单位.机器级程序将内存视为非常大的数组,称为虚拟内存.内存中的每一个字节都由唯一的数字来标识.称为它的地址.

    所有地址的集合即为虚拟地址空间.所以,对于32位的机器,虚拟地址空间地址范围为0~0x8FFFFFFF-1,从0开始,需要减去1.

    1.二进制转16进制

       数学原理: 2^0+2^1+2^2+2^3 = 15

       在16进制中我们使用A~F来表示10,11,12,13,14,15,0~9 不变.

       由此,对一个二进制序列,我们只要从低位开始,每四个位取一个16进制数.如下.

       1111 0001  1000 的16进制表示法为 0xF18

       如果最后一次取数的二进制序列少于4位,高位补0,如下

       11 0001  1000 的16进制表示法为 0x318

       特别当x = 2^n次方时,转16进制方法如下.

       因为有16进制的0代表4个二进制位.所以n = i + 4j. i = 0,1,2,3,16进制表示法为0x(2^i)(j个0)

       比如 二进制序列 100 0000 是 2^6, 6 = 2+1*4,16进制表示法为0x40 

     2.16进制转二进制

        每一个16进制数,写成4个二进制位

        比如.0x7F    0111 1111   

       

    对于一个多字节的程序对象,必须建立俩个规则,对象的地址是什么,内存中如何排列这些字节,假设4字节int变量0x7FFFFFFF存储是连续的,

    有俩种排列方式.

    1.低位在前

    0x00   int的第一个字节 FF

    0x01   int的第二个字节 FF

    0x02   int的第三个字节 FF

    0x03   int的第四个字节 7F

    2.高位在前

    0x00   int的第四个字节 7F

    0x01   int的第三个字节 FF

    0x02   int的第二个字节 FF

    0x03   int的第一个字节 FF

     由此我们导出俩种程序对象在内存中排列的方式,大端法,小端法

    1.有效的低字节在前,小端法

    2.有效的高字节在前.大端法

    影响到三个方面.

    1.跨主机传送数据,比如从使用大端排列的机器传输字节到小端排列的机器.如下,假设要传送的数据是4个字节的int数字,0x7FFFFFFF(人的书写形式),即2147483647

       大端机器的操作如下,将此int的四个字节,存入到一个bye[4]的数组内.[7F,FF,FF,FF,FF,FF,FF],

       小端机器接受到数据如下.[7F,FF,FF,FF,FF,FF,FF],那么小端机器认为低字节在前,即传输过来的数字为0xFFFFFFF7F.

    2.阅读表示整数数据的字节序列时字节顺序也很重要.如下,考虑到反汇编代码

      01 05 43 0b 20 00,这个是我们的书写顺序.

    小端机器解释的顺序为 00 20 0b 43 05 01

    大端机器解释的顺序为 01 05 43 0b 20 00

    3.编写规避正常类型系统的程序时,比如C里面的强制转换和union

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    无符号数编码和有符号整数补码编码

    设一个二进制序列[xw-1.........x0]

       无符号编码,最高位为负权,即符号位:

         X1 = xw-1*2w-1+..........+x0*20

      有符号补码编码为:

        X2 = -xw-1*2w-1+xw-2*2w-2+......................+x0*20

    由以上俩个数学公式,可以导出有符号补码编码整数转无符号编码整数公式

      X2-X1 = -xw-1 * 2w-1 -  xw-1*2w-1 = -xw-1*2w

    即 X1 = X2 + xw-1*2w    X2 = X1 - xw-1*2w

    设,w = 4,考虑如下一个二进制序列[ 1 0 1 1]

    它的无符号整数为 8+2+1=11,有符号整数为 -8+3=-5,

    有 -5 = 11 - 1*2^4=11-16=-5

    有 11 = -5 + 2^4 = -5 + 16 = 11

    对俩个整数相加溢出,即超出编码能容纳的范围,

    无符号数加法

    x +y = x+y 或者 x + y - 2w(即溢出位舍弃),考虑如下代码

    #include <iostream>
    #include<limits.h>
    using namespace std;
    
    
    
    
    int main()
    {
        cout << UINT32_MAX + 1 << endl;
    }

    运行结果为0.原理如下

    0xFFFFFFFF + 1 = 0x1 00000000,溢出舍弃,即0x00000000 = 0x1 00000000 - 2^32 = 2^32 - 2^32

    有符号数补码加法

    x + y = x +y 或者 x+y - 2(正溢出,整数相加变成负数) 或者 x+y + 2(负数相加变成整数)

    int main()
    {
        cout << INT32_MAX + 1 << endl; //2147483647 + 1 = 2147483648 - 2^32 = -2147483648
        cout << INT32_MIN - 1 << endl; // -2147483648 - 1 = -2147483649 + 2^32 = 2147483647
    }

    INT32_MAX 是 0x7FFFFFFF + 1 = 0x80000000 - 0x1 00000000 (2^32) = 0x80000000,第二行同理 

  • 相关阅读:
    ReadMe文档编写规范
    记录配置GPU遇到的问题
    文本分类流程详细总结(keras)
    打包 SyntaxError:Cannot use import statement outside a module browser_init.js
    SQLServer 转mysql
    Sql Server 查询某月有多少天
    nodejs http是使用异步方式调用接口,通过此方法可以实现同步调用
    linux 编译安装amqp扩展
    记一次 hadoop does not have enough number of replicas问题处理
    ldap+squid 实现
  • 原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/9750381.html
Copyright © 2011-2022 走看看