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

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

为什么引入补码

数的原码表示百形式简单,适用于乘除运算,但用原码表示的数进行加减度法运算比较复杂,引知入补码之后,减法运算可以用加法来实现,且数的符号道位也可以当作数值一内样参与运算,因此在计算机中大都采用补码来进行加容减法运算
如: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<stdio.h>
#include<memory.h>
#include<string.h>
#include<stdlib.h>

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 <stdio.h>
#include <string.h>

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

  • 3
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
C语言中,负数的原码、补码和反码用于表示负数的二进制形式。下面是关于负数的原码、补码和反码的解释: 1. 原码(Sign-Magnitude):负数的原码是将其绝对值转换为二进制形式,然后在最高位加上符号位(0表示正数,1表示负数)。例如,-5的原码是10000101(假设使用8位二进制表示)。 2. 反码(Ones' Complement):负数的反码是将其原码的除符号位外的所有位取反。例如,-5的反码是11111010。 3. 补码(Two's Complement):负数补码是将其反码加1。例如,-5的补码是11111011。 以下是一个示例代码,用于获取负数的原码、反码和补码: ```c #include <stdio.h> void printBinary(int num) { unsigned int mask = 1 << (sizeof(int) * 8 - 1); // 使用无符号整数来避免右移时引入符号位 printf("原码:"); for (int i = 0; i < sizeof(int) * 8; i++) { if (num & mask) { printf("1"); } else { printf("0"); } mask >>= 1; } printf("\n"); printf("反码:"); if (num < 0) { num = ~num; } for (int i = 0; i < sizeof(int) * 8; i++) { if (num & mask) { printf("1"); } else { printf("0"); } mask >>= 1; } printf("\n"); printf("补码:"); if (num < 0) { num = ~num + 1; } for (int i = 0; i < sizeof(int) * 8; i++) { if (num & mask) { printf("1"); } else { printf("0"); } mask >>= 1; } printf("\n"); } int main() { int negativeNum = -5; printBinary(negativeNum); return 0; } ``` 在上述示例代码中,负数 `-5` 的原码是 `10000101`,反码是 `11111010`,补码是 `11111011`。该代码通过位操作和循环打印出了负数的原码、反码和补码
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值