无符号 数 oracle,整数的无符号编码和有符号编码

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

无符号编码表示的数 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*2wX2 = 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 #include

using namespacestd;intmain()

{

cout<< UINT32_MAX + 1 <

}

运行结果为0.原理如下

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

有符号数补码加法

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

intmain()

{

cout<< INT32_MAX + 1 <

cout<< INT32_MIN - 1 <

}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值