文档库 最新最全的文档下载
当前位置:文档库 › byte与16进制字符串转换原理原码补码

byte与16进制字符串转换原理原码补码

byte与16进制字符串转换原理原码补码
byte与16进制字符串转换原理原码补码

Java中byte与16进制字符串的互相转换

Java中byte用二进制表示占用8位,而我们知道16进制的每个字符需要用4位二进制位来表示(23 + 22 + 21 + 20 = 15),所以我们就可以把每个byte转换成两个相应的16进制字符,即把byte的高4位和低4位分别转换成相应的16进制字符H和L,并组合起来得到byte转换到16进制字符串的结果new String(H) + new String(L)。即byte用十六进制表示只占2位。同理,相反的转换也是将两个16进制字符转换成一个byte,原理同上。

根据以上原理,我们就可以将byte[] 数组转换为16进制字符串了,当然也可以将16进制字符串转换为byte[]数组了。

1.* Convert byte[] to hex string.这里我们可以将byte转换成int,然后利用Integer.toHexString(int)来转换成16进制

字符串。

2.* @param src byte[] data

3.* @return hex string

4.*/

5.public static String bytesToHexString(byte[] src){

6.StringBuilder stringBuilder = new StringBuilder("");

7.if(src == null|| src.length <= 0) {

8.return null;

9.}

10.for(int i = 0; i < src.length; i++) {

11.int v = src[i] & 0xFF;

12.String hv = Integer.toHexString(v);

13.if(hv.length() < 2) {

14.stringBuilder.append(0);

15.}

16.stringBuilder.append(hv);

17.}

18.return stringBuilder.toString();

19.}

20./**

21.* Convert hex string to byte[]

22.* @param hexString the hex string

23.* @return byte[]

24.*/

25.public static byte[] hexStringToBytes(String hexString) {

26.if(hexString == null|| hexString.equals("")) {

27.return null;

28.}

29.hexString = hexString.toUpperCase();

30.int length = hexString.length() / 2;

31.char[] hexChars = hexString.toCharArray();

32.byte[] d = new byte[length];

33.for(int i = 0; i < length; i++) {

34.int pos = i * 2;

35.d[i] = (byte) (charToByte(hexChars[pos]) << 4| charToByte(hexChars[pos + 1]));

36.}

37.return d;

38.}

39./**

40.* Convert char to byte

41.* @param c char

42.* @return byte

43.*/

44.private byte charToByte(char c) {

45.return(byte) "0123456789ABCDEF".indexOf(c);

46.}

Java代码

1.//将指定byte数组以16进制的形式打印到控制台

2.public static void printHexString( byte[] b) {

3.for(int i = 0; i < b.length; i++) {

4.String hex = Integer.toHexString(b[i] & 0xFF);

5.if(hex.length() == 1) {

6.hex = '0'+ hex;

7.}

8.System.out.print(hex.toUpperCase() );

9.}

10.

11.}

java中byte转换int时为何与0xff进行与运算

在剖析该问题前请看如下代码

Java代码

1.public static String bytes2HexString(byte[] b) {

2.String ret = "";

3.for(int i = 0; i < b.length; i++) {

4.String hex = Integer.toHexString(b[ i ] & 0xFF);

5.if(hex.length() == 1) {

6.hex = '0'+ hex;

7.}

8.ret += hex.toUpperCase();

9.}

10.return ret;

11.}

上面是将byte[]转化十六进制的字符串,注意这里b[ i ] & 0xFF将一个byte和0xFF进行了与运算,然后使用Integer.toHexString取得了十六进制字符串,可以看出

b[ i ] & 0xFF运算后得出的仍然是个int,那么为何要和 0xFF进行与运算呢?直接 Integer.toHexString(b[ i ]);,将byte 强转为int不行吗?答案是不行的.

其原因在于:

1.byte的大小为8bits而int的大小为32bits

2.java的二进制采用的是补码形式

在这里先温习下计算机基础理论

byte是一个字节保存的,有8个位,即8个0、1。

8位的第一个位是符号位,

也就是说0000 0001代表的是数字1

1000 0000代表的就是-1

所以正数最大位0111 1111,也就是数字127

负数最大为1111 1111,也就是数字-128

这里 0 是 00000000 ,而 10000000 是-1 ,正数计算里面去掉了一个0,所有最大值只能是2^7 -1 =127

而负数并没有用去掉0,所以是2^7 = -128

上面说的是二进制原码,但是在java中采用的是补码的形式,下面介绍下什么是补码

1、机器数

一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.

比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3,就是 10000010 。

那么,这里的 00000011 和 10000011 就是机器数。

2、真值

因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。

例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1

3、反码:

一个数如果是正,则它的反码与原码相同;

一个数如果是负,则符号位为1,其余各位是对原码取反;

4、补码:利用溢出,我们可以将减法变成加法

对于十进制数,从9得到5可用减法:

9-4=5 因为4+6=10,我们可以将6作为4的补数

改写为加法:

9+6=15(去掉高位1,也就是减10)得到5.

对于十六进制数,从c到5可用减法:

c-7=5 因为7+9=16 将9作为7的补数

改写为加法:

c+9=15(去掉高位1,也就是减16)得到5.

在计算机中,如果我们用1个字节表示一个数,一个字节有8位,超过8位就进1,在内存中情况为(100000000),进位1被丢弃。

⑴一个数为正,则它的原码、反码、补码相同

⑵一个数为负,刚符号位为1,其余各位是对原码取反,然后整个数加1

- 1的原码为 10000001 - 1的反码为 11111110

+ 1 - 1的补码为 11111111

0的原码为 00000000

0的反码为 11111111(正零和负零的反码相同) +1

0的补码为 100000000(舍掉打头的1,正零和负零的补码相同)

0原码是00000000 -0原码是10000000

0反码是00000000 -0反码是11111111

0补码是00000000

补码没有正0与负0之分

三. 为何要使用原码, 反码和补码

现在我们知道了计算机可以有三种编码方式表示一个数. 对于正数因为三种编码方式的结果都相同:

[+1] = [00000001]原 = [00000001]反 = [00000001]补

所以不需要过多解释. 但是对于负数:

[-1] = [10000001]原 = [11111110]反 = [11111111]补

可见原码, 反码和补码是完全不同的. 既然原码才是被人脑直接识别并用于计算表示方式, 为何还会有反码和补码呢?

首先, 因为人脑可以知道第一位是符号位, 在计算的时候我们会根据符号位, 选择对真值区域的加减. (真值的概念在本文最开头). 但是对于计算机, 加减乘数已经是最基础的运算, 要设计的尽量简单. 计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂! 于是人们想出了将符号位也参与运算的方法. 我们知道, 根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了. 于是人们开始探索 将符号位参与运算, 并且只保留加法的方法. 首先来看原码: 计算十进制的表达式: 1-1=0

1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2

如果用原码表示, 让符号位也参与计算, 显然对于减法来说, 结果是不正确的.这也就是为何计算机内部不使用原码表示一个数.

为了解决原码做减法的问题, 出现了反码: 计算十进制的表达式: 1-1=0

1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0

发现用反码计算减法, 结果的真值部分是正确的. 而唯一的问题其实就出现在"0"这个特殊的数值上. 虽然人们理解上+0和-0是一样的, 但是0带符号是没有任何意义的. 而且会有[0000 0000]原和[1000 0000]原两个编码表示0. 于是补码的出现, 解决了0的符号以及两个编码的问题:

1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原

这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128:

(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]补 + [1000 0001]补 = [1000 0000]补

-1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000]补就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000]原, 这是不正确的)

使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].

因为机器使用补码, 所以对于编程中常用到的32位int类型, 可以表示范围是: [-231, 231-1] 因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.

四原码, 反码, 补码再深入

计算机巧妙地把符号位参与运算, 并且将减法变成了加法, 背后蕴含了怎样的数学原理呢?

将钟表想象成是一个1位的12进制数. 如果当前时间是6点, 我希望将时间设置成4点, 需要怎么做呢?我们可以:

1. 往回拨2个小时: 6 - 2 = 4

2. 往前拨10个小时: (6 + 10) mod 12 = 4

3. 往前拨10+12=22个小时: (6+22) mod 12 =4

2,3方法中的mod是指取模操作, 16 mod 12 =4 即用16除以12后的余数是4.

所以钟表往回拨(减法)的结果可以用往前拨(加法)替代!

现在的焦点就落在了如何用一个正数, 来替代一个负数. 上面的例子我们能感觉出来一些端倪, 发现一些规律. 但是数学是严谨的. 不能靠感觉.

首先介绍一个数学中相关的概念: 同余

同余的概念

两个整数a,b,若它们除以整数m所得的余数相等,则称a,b对于模m同余

记作 a ≡ b (mod m)

读作 a 与 b 关于模 m 同余。

举例说明:

4 mod 12 = 4

16 mod 12 = 4

28 mod 12 = 4

所以4, 16, 28关于模 12 同余.

负数取模

正数进行mod运算是很简单的. 但是负数呢?

下面是关于mod运算的数学定义:

上面是截图, "取下界"符号找不到如何输入(word中粘贴过来后乱码). 下面是使用"L"和"J"替换上图的"取下界"符号:

x mod y = x - y L x / y J

上面公式的意思是:

x mod y等于 x 减去 y 乘上 x与y的商的下界.

以 -3 mod 2 举例:

-3 mod 2

= -3 - 2xL -3/2 J

= -3 - 2xL-1.5J

= -3 - 2x(-2)

= -3 + 4 = 1

所以:

(-2) mod 12 = 12-2=10

(-4) mod 12 = 12-4 = 8

(-5) mod 12 = 12 - 5 = 7

开始证明

再回到时钟的问题上:

回拨2小时 = 前拨10小时

回拨4小时 = 前拨8小时

回拨5小时= 前拨7小时

注意, 这里发现的规律!

结合上面学到的同余的概念.实际上:

(-2) mod 12 = 10

10 mod 12 = 10

-2与10是同余的.

(-4) mod 12 = 8

8 mod 12 = 8

-4与8是同余的.

距离成功越来越近了. 要实现用正数替代负数, 只需要运用同余数的两个定理:

反身性:

a ≡ a (mod m)

这个定理是很显而易见的.

线性运算定理:

如果a ≡ b (mod m),c ≡ d (mod m) 那么:

(1)a ± c ≡ b ± d (mod m)

(2)a * c ≡ b * d (mod m)

如果想看这个定理的证明, 请看:https://www.wendangku.net/doc/6816700649.html,/view/79282.htm

所以:

7 ≡ 7 (mod 12)

(-2) ≡ 10 (mod 12)

7 -2 ≡ 7 + 10 (mod 12)

现在我们为一个负数, 找到了它的正数同余数. 但是并不是7-2 = 7+10, 而是 7 -2 ≡ 7 + 10 (mod 12) , 即计算结果的余数相等.

接下来回到二进制的问题上, 看一下: 2-1=1的问题.

2-1=2+(-1) = [0000 0010]

原 + [1000 0001]

= [0000 0010]

+ [1111 1110]

先到这一步, -1的反码表示是1111 1110. 如果这里将[1111 1110]认为是原码, 则[1111 1110]原 = -126, 这里将符号位除去, 即认为是126.

发现有如下规律:

(-1) mod 127 = 126

126 mod 127 = 126

即:

(-1) ≡ 126 (mod 127)

2-1 ≡ 2+126 (mod 127)

2-1 与 2+126的余数结果是相同的! 而这个余数, 正式我们的期望的计算结果: 2-1=1

所以说一个数的反码, 实际上是这个数对于一个膜的同余数. 而这个膜并不是我们的二进制, 而是所能表示的最大值! 这就和钟表一样, 转了一圈后总能找到在可表示范围内的一个正确的数值!

而2+126很显然相当于钟表转过了一轮, 而因为符号位是参与计算的, 正好和溢出的最高位形成正确的运算结果.

既然反码可以将减法变成加法, 那么现在计算机使用的补码呢? 为什么在反码的基础上加1, 还能得到正确的结果?

2-1=2+(-1) = [0000 0010]

原 + [1000 0001]

= [0000 0010]

+ [1111 1111]

如果把[1111 1111]当成原码, 去除符号位, 则:

[0111 1111]

= 127

其实, 在反码的基础上+1, 只是相当于增加了膜的值:

(-1) mod 128 = 127

127 mod 128 = 127

2-1 ≡ 2+127 (mod 128)

此时, 表盘相当于每128个刻度转一轮. 所以用补码表示的运算结果最小值和最大值应该是[-128, 128].

但是由于0的特殊情况, 没有办法表示128, 所以补码的取值范围是[-128, 127]

计算机中是怎样进行减法,除法,乘方,开方等运算的?

加法有加法器实现,减法是转换成补码的加法来运算

乘法有乘法器实现,除法是移位来实现的

微型计算机只有加减运算,而乘除都转为加减运算。

只有大型机才有乘除运算器

加减乘除一般由CPU直接完成,乘方开方等更复杂的运算一般都是软件实现的。

运算到最底层都是运算电路在工作,加法器,乘法器

乘数、被乘数都要先转化为二进制,二进制的乘法远比十进制简单,比如乘数是1011,只需将将被乘数分别左移3位、1位,移动后补入0,并将这三个数(被乘数左移3位的、被乘数左移1位的及未移位的被乘数)在累加器中相加,所得总和就是积,根据需要积可再转化为十进制。

除法与乘法类似,只不过将左移改为右移,加改成减。实际上减也是通过取补码后再加,因此计算机芯片上的累加器是最繁忙的部分。

程序中是:逆波兰式

汇编中是:位操作

加法模拟减法,乘法模拟除法

Integer.toHexString的参数是int,如果不进行&0xff,那么当一个byte会转换成int时,由于int是32位,而byte只有8位这时会进行补位,

--

Java中的一个byte,其范围是-128~127的,而Integer.toHexString的参数本来是int,如果不进行&0xff,那么当一个byte 会转换成int时,对于负数,会做位扩展,举例来说,一个byte的-1(即0xff),会被转换成int的-1(即0xffffffff),那么转化出的结果就不是我们想要的了。

而0xff默认是整形,所以,一个byte跟0xff相与会先将那个byte转化成整形运算,这样,结果中的高的24个比特就总会被清0,于是结果总是我们想要的。

例如补码11111111的十进制数为-1转换为int时变为11111111111111111111111111111111好多1啊,呵呵!即0xffffffff 但是这个数是不对的,这种补位就会造成误差。

和0xff相与后,高24比特就会被清0了,结果就对了。

MAC地址

是网卡的物理地址,它由48位二进制数表示。其中前面24位表示网络厂商标识符,后24位表示序号。每个不同的网络厂商会有不同的厂商标识符,而每个厂商所生产出来的网卡都是依序号不断变化的,所以每块网卡的MAC地址是世界上独一无二的(特殊情况除外:如要通过修改MAC地址来通过认证时)。一般我们采用六个十六进制数来表示一个完整的MAC地址,如

00:e0:4c:01:02:85。在win98/2000下均可以通过在MS-DOS方式下执行IPCONFIG/ALL命令得到相应的网卡的MAC地址

进制转换和原码补码

必备基础: 第一部分:进制转换 →二进制(Binary):由0~1构成,逢2进1 11B →3D 八进制(Octal):由0~7构成,逢8进1 11Q →9D 十进制(Decimal):由0~9构成,逢10进1 111D →111D 十六进制(Hex):由0~9、A~F构成,逢16进1 11H →17D →两个基本概念 基数:n进制基数为n 111.11D = 1*102 + 1*101 + 1*100 + 1*10-1 + 1*10-2 位权:小数点左边第k位位权为:基数k-1 小数点右边第k位位权为:基数-k →进制转换 1.其他进制→十进制(按权展开求和法) 123.45D = 1*102 + 2*101 + 3*100 + 4*10-1 + 5*10-2 11001.11B = 1*24 + 1*23 + 1*20 + 1*2-1 + 1*2-2 = 16+8+1+0.5+0.25 = 25.75D 123.4Q = 1*82 + 2*81 + 3*80 + 4*8-1 = 64+16+3+0.5 = 83.5D 123.4H = 1*162 + 2*161 + 3*160 + 4*16-1 = 256+32+3+0.25 = 291.25D 2.十进制→其他进制 →整数部分:基数除法,倒序取余。 →小数部分:基数乘法,顺序取整。 76.375D = 1001 100.011 B = 114.3 Q = 4C.6 H 276 0.375*2=0.75-------0 ↓ 38------0 ↑ 0.75*2=1.5--------1↓ 19------0 ↑ 0.5*2=1----------1↓ 9------1 ↑ 4------1 ↑ 2------0 ↑ 1------0 ↑ 0------1 ↑ 8 76 = 114Q 0.375D = 0.3Q 9-----4 ↑ 0.375*8 = 3------3 ↓

计算一个二进制或者十进制的数的原码,反码和补码

import java.util.Scanner; publicclass RadixChange { staticint byteNumber = 8; // 将输入的操作数转换成八位二进制有符号整数,即得到这个数的原码; publicstatic String decimalToBinary(String operand, int choice) { String opeString = " " + operand; String returnVal = null; opeString = opeString.trim(); // char [] src={'0','0','0','0','0','0','0'}; if (choice == 0) { returnVal = Integer.toString( new Integer(operand).intValue(), 2); } else { returnVal = opeString; } /** * 将二进制数据用八位二进制原码表示 */ // 如果是有符号二进制 if (choice == 1) { if (returnVal.codePointAt(0) == 48) for (int i = returnVal.length(); i

进制转换+原码反码补码课堂小测验(有答案)

1、假设某计算机的字长为8位,则十进制数(-66)的补码为_______ [答案:C] A. 01000010 B. 11000010 C. 10111110 D. 10111111 2、假设某计算机的字长为8位,则十进制数(+75)的反码为_______ [答案:A] A. 01001011 B. 11001011 C. 10110100 D. 10110101 3、执行下列二进制数算术加运算10101010+00101010其结果是_______ [答案:A] A. 11010100 B. 11010010 C. 10101010 D. 00101010 4、对于正数,其原码,反码和补码是_______ [答案:A] A. 一致的 B. 不一致的 C. 互为相反的 D. 互为相补的 5、已知8位机器码是10110100,若其为补码时,表示的十进制真值是_______ [答案:A] A. -76 B. -74 C. 74 D. 76 6、已知[X]补=10111010,求X(真值)______。 [答案:A] A. -1000110 B. -1000101

C. 1000100 D. 1000110 7、写出 (176.5)8 的按权展开式。 [答案:(176.5)8 = 182+781 +680 +58-1] 8、(27B.7C)H = (10 0111 1011.0111 11 ) B 9、(36)16= ( 54 )10 10、(456)10 = ( 710 )8 11、 (54)10 = ( 36 )16 12、(1C8)16 = ( 710 )8 13、如果(42)x=(2A)H,则x为_______ [答案:C] A. 2 B. 8 C. 10 D. 16 14、微机内存容量的基本单位是_______ [答案: B] A. 字符 B. 字节 C. 二进制位 D. 扇区 15、十进制数113.25转换成对应的十六进制数是_____________H [答案:B] A. 71.6 B. 71.4 C. 73.4 D. 73.6 16、存储器的1KB存储容量表示_______ [答案: B] A. 1024个二进制位 B. 1024个字节 C.

进制转换及原码反码补码练习题

进制转换练习题 【例题1-1】十进制数1000对应二进制数为______,对应十六进制数为______。 供选择的答案 A:①1111101010 ②1111101000 ③1111101100 ④1111101110 B:①3C8 ②3D8 ③3E8 ④3F8 【例题1-2】十进制小数为0.96875对应的二进制数为______,对应的十六进制数为______。 供选择的答案 A:①0.11111 ②0.111101 ③0.111111 ④ 0.1111111 B:①0.FC ②0.F8 ③0.F2 ④0.F1 【例题1-3】二进制的1000001相当十进制的______,二进制的100.001可以表示为______。 供选择的答案 A:①62 ②63 ③64 ④65 B:①23+2–3②22+2–2③23+2–2④22+2–3 【例题1-4】十进制的100相当于二进制______,十进制的0.110011相当二进制的______。 供选择的答案 A:①1000000 ②1100000 ③1100100 ④1101000 B:①2–1+2–2+2–4+2–5②1–(2–3+2–4) ③1+(–2–3–2–4) ④1–2–3–2–4–2–6 【例题1-5】八进制的100化为十进制为______,十六进制的100化为十进制为______。 供选择的答案 A:①80 ②72 ③64 ④56 B:①160 ②180 ③230 ④256 【例题1-6】在答案群所给出的关系式中正确的为______,在给出的等式中不正确的为______。 供选择的答案 A:①0.1112<0.7510②0.78>0.C16

进制转换+原码反码补码课堂小测验(有答案)doc资料

进制转换+原码反码补码课堂小测验(有答案)

精品文档 收集于网络,如有侵权请联系管理员删除 1、假设某计算机的字长为8位,则十进制数(-66)的补码为_______ [答案:C] A. 01000010 B. 11000010 C. 10111110 D. 10111111 2、假设某计算机的字长为8位,则十进制数(+75)的反码为_______ [答案:A] A. 01001011 B. 11001011 C. 10110100 D. 10110101 3、执行下列二进制数算术加运算10101010+00101010其结果是_______ [答案:A] A. 11010100 B. 11010010 C. 10101010 D. 00101010 4、 对于正数,其原码,反码和补码是_______ [答案:A] A. 一致的 B. 不一致的 C. 互为相反的 D. 互为相补的 5、 已知8位机器码是10110100,若其为补码时,表示的十进制真值是_______ [答案:A] A. -76 B. -74 C. 74 D. 76 6、已知[X]补=10111010,求X (真值)______。 [答案:A] A. -1000110 B. -1000101 C. 1000100 D. 1000110 7、写出 (176.5)8 的按权展开式。 [答案:(176.5)8 = 1?82+7?81 +6?80 +5?8-1] 8、(27B.7C)H = (10 0111 1011.0111 11 ) B 9、(36)16 = ( 54 )10 10、(456)10 = ( 710 )8 11、 (54)10 = ( 36 )16 12、(1C8)16 = ( 710 )8

大学计算机2.理解原码,反码和补码

(转)理解原码,反码和补码 相信大家看到这个标题都不屑一顾,因为在任何一本计算机基础知识书的第一章都有他们的解释,但是在书上我们只能找到一些简单的定义,看过之后不久就忘了。 数值在计算机中表示形式为机器数,计算机只能识别0和1,使用的是二进制,而在日常生活中人们使用的是十进制,正如亚里士多德早就指出的那样,今天十进制的广泛采用,只不过我们绝大多数人生来具有10个手指头这个解剖学事实的结果.尽管在历史上手指计数(5,10进制)的实践要比二或三进制计数出现的晚.(摘自<<数学发展史>>有空大家可以看看哦~,很有意思的). 为了能方便的与二进制转换,就使用了十六进制和八进制. 数值有正负之分,计算机就用一个数的最高位存放符号(0为正,1为负).这就是机器数的原码了. 假设机器能处理的位数为8.即字长为1byte,原码能表示数值的范围为 (-127~-0 +0~127)共256个. 有了数值的表示方法就可以对数进行算术运算.但是很快就发现用带符号位的原码进行乘除运算时结果正确,而在加减运算的时候就出现了问题,如下: 假设字长为8bits ( 1 ) 10- ( 1 )10 = ( 1 )10 + ( -1 )10 = ( 0 )10 (00000001)原+ (10000001)原= (10000010)原= ( -2 ) 显然不正确. 因为在两个整数的加法运算中是没有问题的,于是就发现问题出现在带符号位的负数身上,对除符号位外的其余各位逐位取反就产生了反码.反码的取值空间和原码相同且一一对应. 下面是反码的减法运算: ( 1 )10 - ( 1 ) 10= ( 1 ) 10+ ( -1 ) 10= ( 0 )10 (00000001) 反+ (11111110)反= (11111111)反= ( -0 ) 有问题. ( 1 )10 - ( 2)10 = ( 1 )10 + ( -2 )10 = ( -1 )10 (00000001) 反+ (11111101)反= (11111110)反= ( -1 ) 正确 问题出现在(+0)和(-0)上,在人们的计算概念中零是没有正负之分的.(印度人首先将零作为标记并放入运算之中,包含有零号的印度数学和十进制计数对人类文明的贡献极大). 于是就引入了补码概念. 负数的补码就是对反码加一,而正数不变,正数的原码反码补码是一样的.在补码中用(-128)代替了(-0),所以补码的表示范围为: (-128~0~127)共256个. 注意:(-128)没有相对应的原码和反码, (-128) = (10000000) 补码的加减运算如下: ( 1 ) 10- ( 1 ) 10= ( 1 )10 + ( -1 )10 = ( 0 )10 (00000001)补+ (11111111)补= (00000000)补= ( 0 ) 正确 ( 1 ) 10- ( 2) 10= ( 1 )10 + ( -2 )10 = ( -1 )10 (00000001) 补+ (11111110) 补= (11111111)补= ( -1 ) 正确 所以补码的设计目的是: ⑴使符号位能与有效值部分一起参加运算,从而简化运算规则. ⑵使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计 所有这些转换都是在计算机的最底层进行的,而在我们使用的汇编、C等其他高级语言中使用的都是原码。看了上面这些大家应该对原码、反码、补码有了新的认识了吧!

原码与补码

原码 概念 原码(true form)是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位),该位为0表示正数,该位为1表示负数,其余位表示数值的大小。 优点 简单直观;例如,我们用8位二进制表示一个数, +11的原码为00001011, -11的原码为10001011 缺点 原码不能直接参加运算,可能会出错。 例如数学上,1+(-1)=0, 而在二进制中 原码 00000001+10000001=10000010,换算成十进制为130。 显然出错了. 计算机中所有的数均用0,1编码表示,数字的正负号也不例外,如果一个机器数字长是n位的话,约定最左边一位用作符号位,其余n-1位用于表示数值。

在符号位上用"0"表示正数;用"1"表示负数。数值位表示真值的绝对值。凡不足n-1位的,小数在最低位右边加零;整数则在最高位左边加零已补足n-1位。这种计算机的编码形式叫做原码。 记作X=[X]原。例如在字长n=8的机器内: 小数: [+0.1011]原=0.1011000 [-0.1011]原=1.1011000 整数: [+1011]原=00001011 [-1011]原=10001011 代码中的小数点”.”是在书写时为了清晰起见加上去的,在机器中并不出现。 原码是有符号数的最简单的编码方式,便于输入输出,但作为代码加减运算时较为复杂。 一个字长为n的机器数能表示不同的数字的个数是固定的2^n 个,n=8时2^n=256;用来表示有符号数,数的范围就是-2^n-1~+2^n-1,n=8是这个范围就是-128~+127。但是在不需要考虑数的正负时,就不需要用一位来表示符号位,n位机器数全部用来表示是数值,这时表示数的范围就是0~2^n-1,n=8时这个范围就是0~255.没有符号位的数,称为无符号数。

真值原码反码补码详解和习题

原码、反码和补码的概念 本节要求 掌握原码、反码、补码的概念 知识精讲 数值型数据的表示按小数点的处理可分为定点数和浮点数;按符号位有原码、反码和补码三种形式的机器数。 一.计算机中数据的表示方法 1、数的定点与浮点表示 在计算机内部,通常用两种方法来表示带小数点的数,即所谓的定点数和浮点数。 ①定点数:是小数点在数中的位置是固定不变的数,数的最高位为符号位,小数点可在符号位之后,也可在数的末尾,小数点本身不需要表示出来,它是隐含的。 缺点:只有纯小数或整数才能用定点数表示; ②浮点数:小数点在数中的位置是浮动的、不固定的数。 一般浮点数既有整数部分又有小数部分,通常对于任何一个二进行制数N,总可以表示成:N=±2P×S N、P、S均为二进制数, P为N的阶码,一般为定点整数,常用补码表示,阶码指明小数点在数据中的位置,它决定浮点的表示范围 S为N的尾数,一般为定点小数,常用补码或原码表示,尾数部分给出了浮点数的有效数字位数,它决定了浮点数的精度,且规格化浮点数0.5≤|S|<1; 0.1B=( 1/2 )D =( 2-1)D 0.11B=(1/2 + 1/4 )D =( 2-1+2-2)D 0.111B=(1/2 + 1/4 + 1/8 )D =( 2-1+2-2+2-3)D --------------------------- 在计算机中表示一个浮点数其结构为: 假设用八个二进制位来表示一个浮点数,且阶码部分占4位,其中阶符占一位;尾数部分占4位,尾符也占一位。 若现有一个二进制数N=(101100)2可表示为:2110×0.1011,则该数在机器内的表示形式为:101100B= 10110B * (21)D 101100B= 1011B * (22)D 101100B= 101.1B * (23)D 101100B= 10.11B * (24)D 101100B= 1.011B * (25)D 101100B= 0.1011B * (26110 一个浮点形式的尾数S若满足0.5≤|S|<1,且尾数的最高位数为1,无无效的0,则该浮点数称为规格化数;规格化数可以提高运算的精度。 S为原码表示,则S1=1 规格化数 S为补码表示N为正数,则S1 =1 N为负数,则S1=0

计算机二进制、八进制、十六进制及反码原码补码、逻辑运算

二进制数据的表示法 二进制数据也是采用位置计数法,其位权是以2为底的幂。例如二进制数据110.11,逢2进1,其权的大小顺序为22、21、20、2-1、2-2。对于有n位整数,m位小数的二进制数据用加权系数展开式表示,可写为: ...a0...a(-m))2 (a (n-1)a(n-2) a(n-1) * 2 (n-1)+ a(n-2) *2(n-2) + ...a * 2(0)...+a(-m)* 2(-m) = 二进制数据一般可写为:(a(n-1)a(n-2)…a(1)a(0).a(-1)a(-2)…a(-m))2。 注意: 1.式中aj表示第j位的系数,它为0和1中的某一个数。 2.a(n-1)中的(n-1)为下标,输入法无法打出所以用括号括住,避免混淆。 3.2^2表示2的平方,以此类推。 【例1102】将二进制数据111.01写成加权系数的形式。 解:(111.01)2=(1×2^2)+(1×2^1)+(1×2^0)+(0×2^-1)+(1×2^-2) 二进制和十六进制,八进制一样,都以二的幂来进位的。 二进制运算 二进制数据的算术运算的基本规律和十进制数的运算十分相似。最常用的是加法运算和乘法运算。 1.二进制加法运算 有四种情况:0+0=0 0+1=1 1+0=1 1+1=10 ps:0 进位为1 【例1103】求(1101)2+(1011)2 的和 解: 1 1 0 1 +1 0 1 1 ------------------- 1 1 0 0 0 2.二进制乘法运算 有四种情况:0×0=0 1×0=0 0×1=0 1×1=1 【例1104】求(1110)2 乘(101)2 之积

进制、原码之间的转换技巧

二进制、八进制、十进制与十六进制 一、进制的概念 在计算机语言中常用的进制有二进制、八进制、十进制和十六进制,十进制是最主要的表达形式。 对于进制,有两个基本的概念:基数和运算规则。 基数:基数是指一种进制中组成的基本数字,也就是不能再进行拆分的数字。二进制是0和1;八进制是0-7;十进制是0-9;十六进制是0-9+A-F(大小写均可)。也可以这样简单记忆,假设是n进制的话,基数就是【0,n-1】的数字,基数的个数和进制值相同,二进制有两个基数,十进制有十个基数,依次类推。 运算规则:运算规则就是进位或错位规则。例如对于二进制来说,该规则是“满二进一,借一当二”;对于十进制来说,该规则是“满十进一,借一当十”。其他进制也是这样。二、二、八、十、十六进制基数对照表

三、二进制转化成其他进制 1. 二进制(Binary)——>八进制(Octal) 例子1:将二进制数(10010)2转化成八进制数。 (10010)2=(010 010)2=(2 2)8=(22)8 例子2:将二进制数(0.1010)2转化为八进制数。 (0.10101)2=(0. 101 010)2=(0. 5 2)8=(0.52)8 诀窍:因为每三位二进制数对应一位八进制数,所以,以小数点为界,整数位则将二进制数从右向左每3位一隔开,不足3位的在左边用0填补即可;小数位则将二进制数从左向右每3位一隔开,不足3位的在右边用0填补即可。 2. 二进制(Binary)——>十进制(Decimal) 例子1:将二进制数(10010)2转化成十进制数。

(10010)2=(1x24+0x23+0x22+1x21+0x20)10=(16+0+0+2+0)10=(18) 10例子2:将二进制数(0.10101)2转化为十进制数。 (0.10101)2=(0+1x2-1+0x2-2+1x2-3+0x2-4+1x2-5)10= (0+0.5+0.25+0.125+0.0625+0.03125)10=(0.96875)10 诀窍:以小数点为界,整数位从最后一位(从右向左)开始算,依次列为第0、1、2、3………n,然后将第n位的数(0或1)乘以2的n-1次方,然后相加即可得到整数位的十进制数;小数位则从左向右开始算,依次列为第1、2、3……..n,然后将第n位的数(0或1)乘以2的-n次方,然后相加即可得到小数位的十进制数(按权相加法)。 3. 二进制(Binary)——>十六进制(Hex) 例子1:将二进制数(10010)2转化成十六进制数。 (10010)2=(0001 0010)2=(1 2)16=(12) 16 例子2:将二进制数(0.1010)2转化为十六进制数。 (0.10101)2=(0. 1010 1000)2=(0. A 8)16=(0.A8)16 诀窍:因为每四位二进制数对应一位十六进制数,所以,以小数点为界,整数位则将二进制数从右向左每4位一隔开,不足4位的在左边用0填补即可;小数位则将二进制数从左向右每4位一隔开,不足4位的在右边用0填补即可。 (10010)2=(22)8=(18) 10=(12)16 (0.10101)2=(0.52)8=(0.96875)10=(0.A8)16 四、八进制转化成其他进制 1. 八进制(Octal)——>二进制(Binary) 例子1:将八进制数(751)8转换成二进制数。 (751)8=(7 5 1)8=(111 101 001)2=(111101001)2

计算机中的原码、反码和补码

计算机中的原码、 计算机中的原码、反码和补码
看到这个标题, 很多人有话要说了, 这个东西每一本计算机基础知识的书中都有介绍的, 切! 你还拿出来 Show 什么嘛! 我的原则是你需要就来看一看, 懂就不要去理会, 倒也不必讽刺两句, 我相信总有需要它的人。当初我看书是没看明白的,在网上查了好多资料才有所悟。 前几天跟老婆讲原码、 反码和补码的知识, 老婆似懂非懂, 在这里我发表一下我个人的意见, 浅显的把我所理解的原码、反码和补码的知识总结一下,一来可以给不懂的人来点启示,二来也 可以方便老婆以后记忆复习。理解有不对的地方希望大家予以指出,谢谢! 大家都知道数据在计算机中都是按字节来储存了,1 个字节等于 8 位(1Byte=8bit) ,而计 算机只能识别 0 和 1 这两个数,所以根据排列,1 个字节能代表 256 种不同的信息,即 28(0 和 1 两种可能,8 位排列) ,比如定义一个字节大小的无符号整数(unsigned char) ,那么它能表示 的是 0~255(0~28-1)这些数,一共是 256 个数,因为,前面说了,一个字节只能表示 256 种 不同的信息。别停下,还是一个字节的无符号整数,我们来进一步剖析它,0 是这些数中最小的 一个,我们先假设它在计算机内部就用 8 位二进制表示为 00000000(从理论上来说也可以表 示成其他不同的二进制码,只要这 256 个数每个数对应的二进制码都不相同就可以了) ,再假设 1 表示为 00000001,2 表示为 00000010,3 表示为 00000011,依次类推,那么最大的那个 数 255 在 8 位二进制中就表示为最大的数 11111111,然后,我们把这些二进制码换算成十进制看 看,会发现刚好和我们假设的数是相同的,而事实上,在计算机中,无符号的整数就是按这个原 理来储存的,所以告诉你一个无符号的整数的二进制码,你就可以知道这个数是多少,而且知道 在计算机中,这个数本身就是以这个二进制码来储存的。比如我给你一个 2 个字节大小的二进 制码,首先声明它表示的是无符号的整数:00000000 00000010,我们把前面的 0 省略,换算 一下,它表示的也是数值 2,和前面不同的是,它占了 2 个字节的内存。不同的类型占的内存空 间不同,如在我的电脑中 char 是 1 个字节,int 是 4 个字节,long 是 8 个字节(你的可能不同, 这取决于不同的计算机设置) ,它们的不同之处仅仅是内存大的能表示的不同的信息多些,也就 是能表示的数范围更大些(unsigned int 能表示的范围是 0~28*4-1) ,至于怎么算,其实都是一 样的,直接把二进制与十进制相互转换,二进制就是它在计算机中的样子,十进制就是我们所表 示的数。啊哈,原来这些都是可以计算的呀,我曾经还以为不同的计算机储存的原理是不同的, 取决于商家的喜好呢,呵呵。 说了这么多怎么还没有提到原码、反码和补码呀,别急别急,
心急吃不了热豆腐,呵呵,因为无符号的整数根本就没有原码、反码和补码。 (啊,那不是被欺 骗了,5555````我告诉妈妈去,哥哥欺负我)都说了别急嘛,你就不想想我说了这么半天的无 符号整数,那么有符号的整数怎么办啊? 呵呵,对,只有有符号的整数才有原码、反码和补码的!其他的类型一概没有。虽然我们也 可以用二进制中最小的数去对应最小的负数,最大的也相对应,但是那样不科学,下面来说说科 学的方法。还是说一个字节的整数,不过这次是有符号的啦,1 个字节它不管怎么样还是只能表 示 256 个数, 因为有符号所以我们就把它表示成范围: -128-127。 它在计算机中是怎么储存的呢? 可以这样理解,用最高位表示符号位,如果是 0 表示正数,如果是 1 表示负数,剩下的 7 位用 来储存数的绝对值的话,能表示 27 个数的绝对值,再考虑正负两种情况,27*2 还是 256 个数。 首先定义 0 在计算机中储存为 00000000,对于正数我们依然可以像无符号数那样换算,从

原码、反码和补码

在计算机内,定点数有3种表示法:原码、反码和补码 原码:在数值前直接加一符号位的表示法 最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。[+7]原= 0 0000111B [- 7]原= 1 0000111B 数0的原码有两种形式: [+0]原= 0 0000000B [- 0]原= 1 0000000B 8位二进制原码的表示范围:-127~+127 反码:正数:正数的反码与原码相同。负数:负数的反码,符号位为“1”,数值部分按位取反。 正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。 [+7]反= 0 0000111B [- 7]反= 1 1111000B [+0]反= 0 0000000B [- 0]反= 1 1111111B 8位二进制反码的表示范围:-127~+127 补码:正数:正数的补码和原码相同。负数:负数的补码则是符号位为“1”,数值部分按位取反后再在末位(最低位)加1。也就是“反

码+1”。 正数的补码与其原码相同;负数的补码是在其反码的末位加1。[+7]补= 0 0000111B [- 7]补= 1 1111001B [ 0 ]补= 0 0000000B。 补码在微型机中是一种重要的编码形式,请注意: a.采用补码后,可以方便地将减法运算转化成加法运算,运算过程得到简化。正数的补码即是它所表示的数的真值,而负数的补码的数值部份却不是它所表示的数的真值。采用补码进行运算,所得结果仍为补码。 b.与原码、反码不同,数值0的补码只有一个,即 c.若字长为8位,则补码所表示的范围为-128~+127;进行补码运算时,应注意所得结果不应超过补码所能表示数的范围。

原码补码的转换

最佳答案补码补码举例1、在计算机系统中,数值一律用补码来表示(存储)。 主要原因:使用补码,可以将符号位和其它位统一处理;同时,减法也可按加法来处理。另外,两个用补 码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。 2、补码与原码的转换过程几乎是相同的。 数值的补码表示也分两种情况: (1)正数的补码:与原码相同。 例如,+9的补码是00001001。 (2)负数的补码:符号位为1,其余位为该数绝对值的原码按位取反;然后整个数加1。例如,-7的补码:因为是负数,则符号位为“1”,整个为10000111;其余7位为-7的绝对值+7的原码 0000111按位取反为1111000;再加1,所以-7的补码是11111001。 已知一个数的补码,求原码的操作分两种情况: (1)如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码。 (2)如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1,其余各位取反,然后再整个数加1。 例如,已知一个补码为11111001,则原码是10000111(-7):因为符号位为“1”,表示是一个负数,所以该位不变,仍为“1”;其余7位1111001取反后为0000110;再加1,所以是10000111。 在“闲扯原码、反码、补码”文件中,没有提到一个很重要的概念“模”。我在这里稍微介绍一下“模”的概念: “模”是指一个计量系统的计数范围。如时钟等。计算机也可以看成一个计量机器,它也有一个计量范围,即都存在一个“模”。例如: 时钟的计量范围是0~11,模=12。 表示n位的计算机计量范围是0~2^(n)-1,模=2^(n)。 “模”实质上是计量器产生“溢出”的量,它的值在计量器上表示不出来,计量器上只能表示出模的 余数。任何有模的计量器,均可化减法为加法运算。 例如:假设当前时针指向10点,而准确时间是6点,调整时间可有以下两种拨法: 一种是倒拨4小时,即:10-4=6 另一种是顺拨8小时:10+8=12+6=6 在以12模的系统中,加8和减4效果是一样的,因此凡是减4运算,都可以用加8来代替。 对“模”而言,8和4互为补数。实际上以12模的系统中,11和1,10和2,9和3,7和5,6和6都有这个特 性。共同的特点是两者相加等于模。 对于计算机,其概念和方法完全一样。n位计算机,设n=8,所能表示的最大数是11111111,若再加1称为100000000(9位),但因只有8位,最高位1自然丢失。又回了00000000,所以8位二进制系统的 模为2^8。在这样的系统中减法问题也可以化成加法问题,只需把减数用相应的补数表示就可以 了。把补数用到计算机对数的处理上,就是补码。 另外两个概念 一的补码(one's complement) 指的是正数=原码,负数=反码

记忆和转换原码、反码、补码和移码其实很简单!

记忆和转换原码、反码、补码和移码其实很简单! 最近在备战软考,复习到计算机组成原理的时候,看到书中关于原码、反码、补码和移码的定义异常复杂。看完这些定义以后,我的脑袋瞬间膨胀到原来的二倍!这样变态的公式不管你记不记得住,反正我是记不住!还好,以前对它们有所了解,否则看到这一堆公式,恐怕我早就放弃参加软考的念头了。 其实,没必要弄得这么麻烦,它们完全可以用一两句话就描述得很清楚。 原码: 如果机器字长为n,那么一个数的原码就是一个n位的二进制数有符号数,其中最高位为符号位:正数为0,负数为1。剩下的n-1位为数值位,表示真值的绝对值。凡不足n-1位的,小数在最低位右边加零;整数则在最高位左边加零来补足n-1位。 例如:X = +101011,[X]原= 0010 1011;X = -101011,[X]原= 1010 1011。 注意:正数的原、反、补码都一样。0的原码跟反码都有两个,因为这里0被分为+0和-0。 反码: 知道了原码,那么你只需要具备区分0跟1的能力就可以轻松求出反码。因为反码就是在原码的基础上,符号位不变,其他位按位取反(就是0变1,1变0)就可以了。 例如:X = -101011,[X]原= 1010 1011,[X]反= 1101 0100。 补码: 补码也非常简单,就是在反码的基础上,按照正常的加法运算加1。 例如:X = -101011,[X]原= 1010 1011 ,[X]反= 1101 0100,[X]补= 1101 0101。 也可以在原码的基础上,符号位不变,从右至左遇到第一个1以前(包括这个1)什么都不变,以后按位取反即可。 [X]原= 1000 0110,[X]补= 1111 1010 注意:0的补码是唯一的,如果机器字长为8,那么[0]补=0000 0000。 移码: 移码最简单了,不管正负数,只要将其补码的符号位取反即可。 例如:X = -101011,[X]原= 1010 1011,[X]反= 1101 0100,[X]补= 1101 0101,[X]移= 0101 0101。

相关文档
相关文档 最新文档