求负数补码的3种方法,为什么引用补码,用c语言实现

求补码的方法

    • 正数没有争议就是原码等于补码和反码
    • 为什么引入补码
    • 求负数反码的两种方法
      • 方法1:课本
      • 方法2:利用相反数减法求补码
      • 方法3:简化过程求补码
    • 方法三:c语言代码
      • memset函数的使用

正数没有争议就是原码等于补码和反码

为什么引入补码

数的原码表示百形式简单,适用于乘除运算,但用原码表示的数进行加减度法运算比较复杂,引知入补码之后,减法运算可以用加法来实现,且数的符号道位也可以当作数值一内样参与运算,因此在计算机中大都采用补码来进行加容减法运算
如:2 - 1 = 2 + (-1) 这样统一成加法,计算机底层设计可以只用加法运算器就可以实现+,-运算,设计越简单就可以加快处理得速度

引自:百度百科
补码“模”概念的引入、负数补码的实质、以及补码和真值之间的关系所揭示的补码符号位所具有的数学特征,无不体现了补码在计算机中表示数值型数据的优势,和原码、反码等相比可表现在如下方面 [3] :
(1)解决了符号的表示的问题 [3] ;
(2)可以将减法运算转化为补码的加法运算来实现,克服了原码加减法运算繁杂的弊端,可有效简化运算器的设计 [3] ;
(3)在计算机中,利用电子器件的特点实现补码和真值、原码之间的相互转换,非常容易 [3] ;
(4)补码表示统一了符号位和数值位,使得符号位可以和数值位一起直接参与运算,这也为后面设计乘法器除法器等运算器件提供了极大的方便。总之,补码概念的引入和当时运算器设计的背景不无关系,从设计者角度,既要考虑表示的数的类型(小数、整数、实数和复数)、数值范围和精确度,又要考虑数据存储和处理所需要的硬件代价。因此,使用补码来表示机器数并得到广泛的应用,也就不难理解了。 [3]

求负数反码的两种方法

方法1:课本

负数的补码是在原码的基础上除符号位外其余位取反后+1

如,已知:-9 补码是:1000 1001
下面求-9 补码:1000 1001 除符号位取反
下面求-9 补码:1111 0110 取反后加1
下面求-9 补码:1111 0111

方法2:利用相反数减法求补码

“正数的补码,是其本身。 负数的补码,就用它的正数,减一取反,即可得到补码。

-9 相反数9:0000 1001
先减一:0000 1001 - 1 = 0000 1000;
再取反:1111 0111。
所以有:-9 补码 = 1111 0111。

方法3:简化过程求补码

  1. 求出负数绝对值的原码
  2. 从原码的最后一位数码位往前数,当遇到第一个1时停在此位置
  3. 将第一个1前面的数码全部求反

下面求-9 补码:
找到右边的第一个1:0000 1001 发现在最后一位
除了右边的第一个1:1111 0111 全部取反(包括符号位置)
所以有:-9 补码 = 1111 0111。

方法三:c语言代码

以下代码求了-128 ~ -1的所有补码

/*
负数补码还原成原码是这样的:
1. 从补码的最后一位数码位往前数,遇到第一个1时停止
2. 将第一个1前的全部数码取反
3. 将第一个数码置1(原来肯定是0,因为我们这里只讨论负数的补码)

下面求-9 补码:
先减一:0000 1001 - 1 = 0000 1000; 	1. 找到右边第一个1 
再取反:1111 0111。						2. 1左边的数全部取反,右边的1因为减去了1变成0,取反后还是1,相当于不变 
所以有:-9 补码 = 1111 0111。			3. 得到负数的补码 
*/ 
#include
#include
#include
#include

int arr[8];    //范围为 -128 ~ +127

void Complement(int number)    //求负数补码
{
	int number_0 = number;  //记录当前负数 
    number=abs(number);    //取绝对值
    int i=7;
    while(number!=0) //求出其绝对值原码
    {
        arr[i]=number%2;
//        printf("arr[%d]=%d\n",i,arr[i]); 
        i--;
//        printf("number=%d\n",number); 
        number/=2;
        
    }
    for(i=7;i>=0;i--)
    {
        if(arr[i]==1)
        {
            int j;
            for(j=0;j<i;j++)    //从右往左数,第一个1左边的数取反 
                if(arr[j]==1)
                    arr[j]=0;
                    else
                    arr[j]=1;
            break;
        }
    }
    printf("%d\t=\t",number_0); 
    for(i=0;i<=7;i++)
        printf("%d",arr[i]);    
    printf("\n");
    memset(arr,0,sizeof(arr));    //重置数组各项为0 
}

int main()
{
    int i;
    for(i=-128;i<=-1;i++)    // 求 -128 ~ -1 的补码 
        Complement(i);    
    return 0;
}

memset函数的使用

/*
void *memset(void *str, int c, size_t n)
参数
str -- 指向要填充的内存块。
c -- 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
n -- 要被设置为该值的字节数。
*/ 
#include 
#include 

int main ()
{
   char str[50];

   strcpy(str,"This is string.h library function");
   puts(str);//This is string.h library function

   memset(str,'0',7);
   puts(str);//0000000 string.h library function 
   
   return(0);
}

转自这位老哥:https://www.cnblogs.com/chiweiming/p/8932140.html

你可能感兴趣的:(c语言,计算机组成原理)