java求反码_Java机器数之原码反码补码
机器数之原码反码补码
基本概念
在计算机中,⼀串数码作为⼀个整体来处理或运算的,称为⼀个计算机字,简称字。字通常分为若⼲个字节(每个字节⼀般是8位)。在存储器中,通常每个单元存储⼀个字,因此每个字都是可以寻址的。字的长度⽤位数来表⽰。
在计算机的运算器、控制器中,通常都是以字为单位进⾏传送的。字出现在不同的地址其含义是不相同。例如,送往控制器去的字是指令,⽽送往运算器去的字就是⼀个数。
字长
字长是指计算机的每个字所包含的位数。字长是CPU的主要技术指标之⼀,指的是CPU⼀次能并⾏处理的⼆进制位数,字长总是8的整数倍,通常PC机的字长为16位(早期),32位,64位。
字节:
字节是指⼀⼩组相邻的⼆进制数码。通常是8位作为⼀个字节。它是构成信息的⼀个⼩单位,并作为⼀个整体来参加操作,⽐字⼩,是构成字的单位。在微型计算机中,通常⽤多少字节来表⽰存储器的存储容量。
机器数:
机器数(computer number)是将符号"数字化"的数,是数字在计算机中的⼆进制表⽰形式。机器数有2个特点:⼀是符号数字化,⼆是其数的⼤⼩受机器字长的限制.
数的符号数值化。实⽤的数据有正数和负数,由于计算机内部的硬件只能表⽰两种物理状态(⽤0和1表⽰),因此实⽤数据的正号“+”或负号“-”,在机器⾥就⽤⼀位⼆进制的0或1来区别。通常这个符号放在⼆进制数的最⾼位,称符号位,以0代表符号“+”,以1代表符
号“-”。
⼆进制的位数受机器设备的限制。机器内部设备⼀次能表⽰的⼆进制位数叫机器的字长,⼀台机器的字长是固定的。字长8位叫⼀个字节(Byte),机器字长⼀般都是字节的整数倍,如字长8位、16位、32位、64位。
如⼀个⼗进制的数为+7,计算机的字长为16,那么该数字的机器数为0000 0000 0111;如果是-7,则表
⽰为1000 0000 000 0111;
真值:
因为有符号占据⼀位,数的形式值就不等于真正的数值,带符号位的机器数对应的数值称为机器数的真值。 例如⼆进制真值数-011011,它的机器数为 1011011。
如 0000 1100(机)=+0000 1100(真)=+12; 1000 1100(机)=-0000 1100(真)=-12;
机器码的原码反码补码的三种表⽰形式
原码:
将数的真值形式中“+”号⽤“0”表⽰,“-”号⽤“1”表⽰时,叫做数的原码形式,简称原码。 若计算机的字长为n位, X数字为正时, [X]原=X; X为负值时,将X的绝对值|X|的符号位变为1即可.
如(字长为8)
[+1]原=0000 0001; [-1]原=1000 0001; 8位⼆进制的范围为[-127,127];
反码:
反码正是解决符号位参与运算⽽产⽣, 正数的反码为本⾝, 负数的反码是其符号位不变其余位取反(~).
[+1]=[0000 0001]原=[0000 0001]反
[-1]=[1000 0001]原=[1111 1110]反
补码:
补码是同余概念引⼊的,补码的表⽰规则也很简单:正数的补码为期本⾝,负数的补码为其反码再加1;
即X为正: [X]补=[X];X为负:[X]补=[X]反+1;
[+1]=[0000 0001]原=[0000 0001]反=[0000 0001]补
[-1]=[1000 0001]原=[1111 1110]反=[1111 1111]补
原码反码补码的由来
原码表⽰法⽐较直观,它的数值部分就是该数的绝对值,⽽且与真值、⼗进制数的转换⼗分⽅便。但是它的加减法运算较复杂。当两数相加时,机器要⾸先判断两数的符号是否相同,如果相同则两数相加,若符号不同,则两数相减。在做减法前,还要判断两数绝对值的⼤⼩,然后⽤⼤数减去⼩数,最后再确
定差的符号,换⾔之,⽤这样⼀种直接的形式进⾏加运算时,负数的符号位不能与其数值部分⼀道参加运算,⽽必须利⽤单独的线路确定和的符号位。
为了解决符号位参加运算的问题,引进反码. 将符号位参与运算:
负75的补码怎么求1-1=1+(-1)=[00000001]原+[10000001]原=[00000001]反+[11111110]反=[11111111]反=[10000000]原=-0;
使⽤反码时发现⼀个特殊值"0",会存在+0和-0两种原码即[00000000]原和[10000000]原.
为了解决0这个特殊的值,另外反码运算由于循环进位需要⼆次运算⽽引⼊补码.
`1-1=1+(-1)=[00000001]原+[10000001]原=[00000001]补+[11111111]补==[10000000]补=[00000000]原=0;`
这样,+0和-0的问题就不存在,⽽且还可以⽤[1000 0000]表⽰-128;
即-1+(-127)=[1111 1111]补+[1000 0001]补=[1000 0000]补,但计算机实际上是⽤-0表⽰-128,所以-128并没有原码和反码.
使⽤补码, 不仅仅修复了0的符号以及存在两个编码的问题, ⽽且还能够多表⽰⼀个最低数. 这就是为什么8位⼆进制, 使⽤原码或反码表⽰的范围为[-127, +127], ⽽使⽤补码表⽰的范围为[-128, 127].
因为机器使⽤补码, 所以对于编程中常⽤到的32位int类型, 可以表⽰范围是: [-231, 231-1]即[0x80000000,0x7fffffff], 因为第⼀位表⽰的是符号位.⽽使⽤补码表⽰时⼜可以多保存⼀个最⼩值.
同余概念
同余定理:给定⼀个正整数m,如果两个整数a和b满⾜(a-b)能够被m整除,即(a-b)/m得到⼀个整数,那么就称整数a与b对模m同余,记作a≡b(mod m)。对模m同余是整数的⼀个等价关系。
假定当前时间为北京时间6点整,有⼀只⼿表却是8点整,⽐北京时间快了2⼩时,校准的⽅法有两种,⼀种是倒拨2⼩时,⼀种是正拨10⼩时。若规定倒拨是做减法,正拨是做加法,那么对⼿表来讲减2与加10是等价的,也就是说减2可以⽤加10来实现。这是因为8加10等于18,然⽽⼿表最⼤只能指⽰12,当⼤于12时12⾃然丢失,18减去12就只剩6了。这说明减法在⼀定条件下,是可以⽤加法来代替的。这⾥“12”称为“模”,10称为“-2”对模12的补数。推⼴到⼀般则有:
A –
B = A + ( – B + M ) = A + ( – B )补
反码的运算规则
1.反码运算时,其符号位与数值⼀起参加运算。
2.反码的符号位相加后,如果有进位出现,则要把它送回到最低位去相加(循环进位)。
3.⽤反码运算,其运算结果亦为反码。在转换为真值时,若符号位为0,数位不变;若符号位为1,应将结果求反才是其真值。
如 x=+1101,Y=+0110,⽤反码计算Z=X-Y;
[01101]反+[11001]反=[01101]+[11001]+1=[00111]反;其真值Z=+0111;
采⽤反码运算较好的解决了原码运算所遇到的困难或问题,但由于循环进位需要⼆次算术相加,延长了计算时间,这同样给电路带来⿇烦。⽽采⽤下述的补码运算则可避免循环进位的两次计算,同时,采⽤补码运算对溢出的判断也较采⽤反码简单的多,所以机器中的算术运算普遍采⽤补码运算。
补码运算规则
1.补码运算时,其符号位与数值部分⼀起参加运算。
2.补码的符号位相加后,如果有进位出现,要把这个进位舍去(⾃然丢失)。
3.⽤补码运算,其运算结果亦为补码。在转换为真值时,若符号位为0,数位不变;若符号位为1,应将结果求补才是其真值。
如:X=+1101,Y=+0110,⽤补码计算Z=X-Y;
[X]补+[-Y]补=[01101]补+[11010]补=01101+11010=100111,其真值为Z=+0111;
如X=+0110,Y=+1101,⽤补码计算Z=X-Y;
[X]补+[-Y]补=[00110]+[10011]=[11001]补,其真值为Z=-0111.
溢出及补码溢出的判断
⽆论采⽤何种机器数,只要运算的结果⼤于数值设备所能表⽰数的范围,就会产⽣溢出。 溢出现象应当作⼀种故障来处理,因为它使结果数发⽣错误。异号两数相加时,实际是两数的绝对值相减,不可能产⽣溢出,但有可能出现正常进位;同号两数相加时,实际上是两数的绝对值相加,既可能产⽣溢出,也可能出现正常进位。
由于补码运算存在符号位进位⾃然丢失⽽运算结果正确的问题,因此,应区分补码的溢出与正常进位。
例如,某数字设备⽤5位⼆进制表⽰数,其数字范围为[-16,15],如果两数字相加减得到的数字超出该范围则溢出.如:
[+9]补+[+3]补=01001+00011=01100=+12;正确
[-9]补+[-3]补=10111+11101=110100=10100(符号位进位⾃然丢失),真值为-1100=-12;
[+9]补+[12]补=01001+01100=10101,真值为-1011=-11;溢出
[-9]补+[-12]补=10111+10100=101011,真值为01011=+11,溢出
⼀般可以⽤异或(^)来判断补码溢出问题(单符号位补码):
运算结果,若 Cs^Cp =0 ⽆溢出,若 Cs^Cp =1 有溢出,
(Cs是符号位的进位,Cp是最⾼数值位的进位,^表⽰异或)