二进制原码、反码、补码运算及标志位

二进制原码、反码、补码运算及标志位,第1张

原码

正整数的原码:这个数的二进制,符号位为0;正整数的原码=补码=反码

例1:+66

66的二进制:1000010,所以+66的原码: 0 1000010 =补码: 0 1000010=反码: 0 1000010

负整数的原码:仍是这个数的二进制,符号位为1;负整数的原码、反码、补码计算:先求原码,再求反码,最后求补码;

原码转换为反码:符号位不变,数值位按位取反;

原码转换为补码:符号位不变,数值位按位取反,末尾在+1;

例2:-66

66的二进制:1000010,所以-66的原码:1 1000010  补码:1 0111101 反码:1 0111110

二、二进制原码、反码、补码的加减运算及标志位

1补码加减基本公式

加法:

整数 [A]补+[B]补=[A+B]补 (mod 2n+1)

小数 [A]补+[B]补=[A+B]补 (mod 2)jianfa

减法:

整数 [A-B]补=[A]补+[-B]补 (mod 2n+1)

小数 [A-B]补=[A]补+[-B]补 (mod 2)

2标志位

CF(Carry Flag) :   进为标志位。主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0。在8位二进制中,如果计算的结果超过 [0,255] 的范围,就有进位,CF就被置为1,如果结果再 [-128,127] 范围内,就是没有进位CF被置为0。

OF(Overflow Flag) :溢出。用于反映有符号数加减运算所得结果是否溢出。如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值被清为0。在8位二进制中,如果一个运算的结果最终超过 [-128,127] 无论是大于127还是小于-128就被认为是溢出,OF被置为1,如果结果在 [-128,127] 就认为没溢出OF被置为0。

SF(Sign Flag) :符号标志。用来反映运算结果的符号位,它与运算结果的最高位相同。在微机系统中,有符号数采用补码表示法,所以,SF也就反映运算结果的正负号。运算结果为正数时,SF的值为0,否则其值为1。

ZF(Zero Flag) :零标志。用来反映运算结果是否为0。如果运算结果为0,则其值为1,否则其值为0。在判断运算结果是否为0时,可使用此标志位。

PF(Parity Flag) :奇偶标志PF用于反映运算结果中“1”的个数的奇偶性。如果“1”的个数为偶数,则PF的值为1,否则其值为0。

AF(Auxiliary Carry Flag) :辅助进位标志。在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0:(1)、在字 *** 作时,发生低字节向高字节进位或借位时;(2)、在字节 *** 作时,发生低4位向高4位进位或借位时。

在计算机系统中,数值,一律采用补码表示和存储。

这就是说,计算机中,并没有原码和反码。

原码和反码,只是在求补码时,表现一下存在感而已。

但是,求补码,还有更正规的方法,完全可以不经过原码反码,就求出补码。

由补码,再求其代表的数值,也可以不用原码反码。

那么,就可以说,原码和反码,都没有任何用处。

-----------------------

补码,是什么呢?

其实,补码,就是一个“代替负数做运算”的正数。

使用了补码,计算机中就没有负数了,也就没有减法了。

那么,计算机只需要一个加法器,就可以走遍天下了。

补码的用处之一,就是简化计算机的硬件。

-----------------------

补码(也就是正数),怎么就能代表负数呢?

其实,道理也很简单。

你看 2 位 10 进制数吧:

  25 - 1 = 24

  25 + 99 = (一百) 24

进位是 10^2 = 100,这也是 2 位数的计数周期。

这个进位,显然不在 2 位数之中,那就舍弃吧。

只取 2 位数的结果,+99 和-1 的作用,就是相同的。

只要舍弃了进位,正数,就可以代替负数。

这个正数,就是“负数的补数”。

求补数的公式: 补数 = 负数 + 周期。

-----------------------

在三角函数中,大家都知道:

  -π/2 和 +3π/2,这两个角度,功能也是相同的。

负角度,和正角度,要怎么变换呢? 

也是用这样的公式: 正角度 = 负角度 + 周期(2π)。

-----------------------

计算机用二进制,补数,就改称为:补码。

8 位 2 进制是:0000 0000~1111 1111 (十进制 255)。

其计数周期是:2^8 = 256。

此时,-1 就可以用 255  (1111 1111)  代替。

同理,-2 的补码就是 254 (1111 1110)。

。。。

正数,本身就是正数,必须直接参加运算,不许再作任何变换。

所以,正数,根本就没有补数(补码)。

以上就是“求补码的正规做法”。

从中可以看到,并没有使用原码和反码,就把补码求出来了。

-----------------------

示例,5 - 7 = -2,用补码计算如下:

     5= 0000 0101

 -7 的补码  = 1111 1001

-相加-------------

   得: (1)   1111 1110   = -2 的补码

舍弃进位,只取 8 位,结果就是正确的。

借助于补码,就可以用加法,实现减法运算。

原码和反码,都没有这种功能。

所以,在计算机中,根本就不使用原码和反码。

那么,原码和反码是什么呢?

它们只是老师讲课的资料而已,实际上,它们什么都不是。

原码:原码是二进制数字的一种简单的表示法。二进制首位为符号位,1代表负,0代表正。

反码:反码可由原码得到。如果是正数,反码与原码相同;如果是负数,反码是其原码(符号位除外)各位取反而得到的。

补码:补码可由原码得到。如果是正数,补码与原码相同;如果是负数,补码是对其原码(除符号位外)各位取反,并在末位加1而得到的(有进位则进位,但不改变符号位)。

python有按位取反的 *** 作符:~   但是对负整数要小心 *** 作,因为在计算机系统中,数值一律用补码来表示和存储的。

#include<stdioh>

#include<stdlibh>

#include<mathh>

#include<conioh>

void convert(int num);

void oppose(int n);

int a[16];

void main(void)

{

int num,jdz;

char ans;

while(1)

{

printf("请输入任意一个十进制整数: ");

scanf("%d",&num);

printf("\n");

printf("其绝对值为: ");

jdz=abs(num);

printf("%d\n\n",jdz);

printf("其原码为: \n");

convert(jdz);

printf("\n\n");

if(num>=0)

{

printf("其补码为: \n");

convert(jdz);

printf("\n\n");

}

else

{

printf("其补码为: \n");

oppose(a[16]);

printf("\n\n");

}

printf("按回车键继续或按ESC键结束程序!!!\n");

ans=getch();

while(ans!=13 && ans!=27)

{

ans=getch();

}

if(ans==13) system("cls");

if(ans==27)

{

system("cls");

printf("谢谢使用!!!\n");

break;

}

}

}

void convert(int num) /定义转化为原码的函数/

{

int i;

a[0]=num%2;

for(i=1;i<=15;i++)

{

a[i]=(num/2)%2;

num/=2;

}

for(i=15;i>=0;i--)

printf("%2d",a[i]);

}

void oppose(int n) /定义转化为补码的函数/

{

int i;

for(i=0;i<=15;i++)

{

switch(a[i])

{

case 1:a[i]=0;break;

case 0:a[i]=1;break;

}

}

for(i=0;i<=15;i++)

{

a[i]++;

if(a[i]>1) a[i]=0;

else break;

}

for(i=15;i>=0;i--)

printf("%2d",a[i]);

}

       在计算机中,使用二进制表达数字,例如,一个字节(8位)可表示的范围是0到255(在不考虑符号的情况下),即00000000到11111111。

考虑到数字有正负,我们第一时间想到,空出一位来表示符号位,例如0表示正,1表示负。则理论上我们表示的范围是-127到+127。这种表达 方式简单明了,好理解,但是有如下几个缺点:

在介绍补码之前,我们先来看看几个相关的概念,第一个就是原码

以一个字节为例,例如:

原码表示有简单易懂的优点,但是原码的符号位不能直接参与运算,必须和其他位分开,这就增加了硬件的开销和复杂性。

上面是的定义和反码的计算方式,我们可以以一种简单的方式概括为:

一个数的反码为这个数的绝对值各位取反

反码码是数值存储的一种,多应用于系统环境设置,如linux平台的目录和文件的默认权限的设置umask,就是使用反码原理。

来到这边文章的重点了,在计算机里面,定点数既不是使用原码表示,也不是使用反码表示,而是使用 补码

百科解释如下

首先,我们阐述下补码的计算方式

例如

补码的特性

以-11举例

-11 原码为 10001011

-11 补码为 11110101

相加为10000000(高位溢出)=128,这个128即为8位定点数的模

这个也是补码的优势之一,原码和补码的转换,可以使用同一套规则,我们以一个负数为例

-11的原码为10001011

通过补码的规则转为之后为11110101,此为-11的补码

该补码再通过相同的规则转换为(11110101的反码加1),10001011

在原码里面,+0和-0的表示方式不同,运算和表达的时候需要增加一些额外的逻辑,在补码里面则没有这个烦恼,补码的+0和-0的表示方式均为00000000(以8位为例)

这也是补码的优势之一,这样可以简化电路逻辑,我们这里面举个简单的例子

11+(-2)

11的补码为00001011

-2的补码为11111110

直接相加加过为00001001=9

补码只是一种相对合理的编码方案。这个方案在负数的机器表示中解决了3个问题:

阮一峰博客

在计算机系统中,数值,一律用补码来表示和存储。

补码,其实,就是一个“代替负数进行运算”的正数。

使用了补码(正数)之后,在计算机中,就没有负数了。

随之而来的就是:减法运算,也都不存在了。

所以,借助于补码,计算机只需要配置一个加法器,就能走遍天下。

使用补码的目的,也就是:简化计算机的硬件。

而原码、反码,都没有这种功能,所以,计算机中,根本就不用它们。

原码和反码,只能在纸上写一写而已。

在计算机中,原码和反码,都是不存在的。

它们之间你怎么写,都没有关系,反正,都没有任何用处!

---------------------

补码(就是正数),怎么就能代替负数呢?

你看时针:倒拨 3 小时,可以用正拨 9 小时代替吧?

你看三角函数:-π/2、+3π/2,两者的函数值也是相同的吧?

10 进制数,如果限定只用 2 位 ,那么就会有:

   25 - 1 = 24

   25 + 99 = (一百) 24

如果忽略进位一百(10^2),+99 就可以代替-1。

上面所说的这些正数,就是“负数的补数”。

求补数的公式是: 补数(即正数)= 负数 + 周期。

正数,必须直接就参加运算,不可再做任何变换。

就是说:正数,本身就已经是正数了,它并不存在什么补数。

---------------------

计算机用二进制,补数,那就称为“补码”了。

8 位 2 进制的周期,是:2^8 = 256。

8 位 2 进制,总共可以组成 256 个代码。

用其中的一半(即 128 个)代表负数,就是:-1 ~ -128。

那么:

-1 的补码,就是:-1 + 256 = 255 = 1111 1111(二进制)。

-2 的补码是:-2 + 256 = 254 = 1111 1110。

。。。

-128 的补码,就是:128 = 1000 0000。

---------------------

至此,你就可以推出“补码的定义式”:

 当 X >= 0,  [ X ]补 =  X;     零和正数不用变换。

 当 X < 0,[ X ]补 =  X + 2^n。 n 是补码的位数。

这是通用的公式。

在严谨一点的书上,都有这种公式,你去翻翻书吧。

---------------------

按照公式求补码,是极为简便的,而且还能理解补码的意义。

而且,反过来求(由补码求数值),也是很方便的。

实际上,你只要会“补码与数值”的互换,就够用了。

那么,没有必要学“原码反码取反加一符号位不变”了。

况且,原码和反码比补码,还少了一个数,取反加一,也无法使用。

当然,那些数学不好的老师,也只能使用这些“隔路”的花样。

---------------------

算式 5 - 7 =-2,计算机用八位补码计算如下:

    5 = 0000 0101

 [-7]补码 = 1111 1001

--相加-----------

  得: (1) 1111 1110 = [-2]补码

舍弃了进位,结果,就是正确的。

---------------------

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/12163771.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存