首页 > 其他分享 >原码、反码、补码再探

原码、反码、补码再探

时间:2023-12-02 11:33:05浏览次数:33  
标签:反码 space 57 补码 1100 原码

原码、反码、补码再探

概述

三个计算机用来表达负数的形式。

  • 原码
    • 通过第一位的 \(0\) 来直接表示正数,\(1\) 来直接表示负数。
    • 然而计算机并不用这种方式。
  • 反码
    • 即把要表示的负数的绝对值对应的二进制全部取反来表示。
    • 坏处是 \(0\) 有两种表达方式,全 \(0\) 和全 \(1\) ,所以也不常用。
  • 补码
    • 即把要表示的负数的绝对值对应的二进制全部取反后再加一来表示。
    • 计算机用这种方式就很方便。

转换

转出

对于 \(-57\)

\(57\) 的二进制:

\(0011\space1001\)

  • 原码
    • \(1011\space1001\)
  • 反码
    • \(1100\space 0110\)
  • 补码
    • \(1100\space 0111\)

转回

  • 原码 \(1011\space 1001\)
    • \(-0011\space 1001 = -57\)
  • 反码 \(1100\space 0110\)
    • 取反加一
    • \(-2^7 + 2^6 + 2^2 + 2^1 = -58\)
    • \(-58 + 1 = -57\)
  • 补码 \(1100\space 0111\)
    • 直接取反
    • \(-2^7 + 2^6 + 2^2 +2^1 + 2^0 = -57\)

计算

计算机计算二进制减法:

\(66-57 = 9\)

\(67 = 0100\space0010\)

\(-57 = 1100\space 0111\)

\[\space\space\space 0100\space0010 \]

\[+1100\space0111 \]

\[\space10000\space1001 \]

这个数字溢出了 \(1\) 位,所以去低位数的 \(8\) 位,得到的答案就是 \(0000\space1001\),也就是十进制下的 \(9\) 。

补码的设计使得计算机可以化减为加。

但谈论补码时,务必要确定总位数,如 char 类型的 \(1100\space0111\) 和 int 类型的 \(0\dots0\space 1100\space 0111\) 表示的可不是同一个数字。

\(memset\)

到这里就可以解释为什么memset只对于 \(-1\) 和 \(0\) 有一一对应的赋值。

首先 memset 按字节赋值,即对于每个字节赋予你给定的值。

对于 \(0\) ,在补码体系下,每个字节都是 \(0\),所以对应。

对于 \(-1\),补码体系下,对于一个字节 \(1111\space1111\),每个字节都是 \(1111\space1111\),所以对应。

依照原理,memset \(0xff\) 即 \(1111\space 1111\) 自然也可以把数组初始化为 \(-1\)。

标签:反码,space,57,补码,1100,原码
From: https://www.cnblogs.com/kdlyh/p/17871394.html

相关文章

  • 补码减法与溢出
    已知二进制数x=-0.11011,y=0.10101,用补码计算x-y,同时指出运算结果是否溢出。(设字长8位)。如何求负的小数的二进制补码?负的小数的二进制补码可以通过以下步骤求得:将小数部分转换为二进制形式。将整数部分和小数部分合并为原码。将原码取反得到反码。对反码加1得到补码。二进......
  • 补码表示法
    所谓的补码表示法,它是有符号整数最常用的二进制表示法。对正数求反码(即对每个位进行NOT运算),然后加1,舍弃MSB的任何进位,就可以得到这个数字的负数。表示+1的0001的反码是1110,加1就可以得到表示–1的1111。同理,+2是0010,它的反码是1101,再加1就可以得到表示–2的1110。......
  • 补码反码
    #include<bits/stdc++.h>usingnamespacestd;intmain(){boolTGDCN=true;strings;stringa;cin>>s;a=s;if(s[0]=='0'){cout<<s;}else{for(inti=1;i<s.size();......
  • 原码--转--反码--补码
    #include<bits/stdc++.h>usingnamespacestd;intmain(){ stringa; cin>>a; intn=a.size(); if(a[0]=='0'){ cout<<a; }else{ for(inti=1;i<=a.size();i++){ if(a[i]=='1'){ a[i]='0'; }else{......
  • 原码转补码反码
    #include<bits/stdc++.h>usingnamespacestd;stringa;intc=0;voidfam(){ if(a[0]=='0'){ cout<<a; }else{ cout<<'1'; for(inti=1;i<a.size();i++){ if(a[i]=='0'){ cout<<'1';......
  • 原码转反补码
    #include<iostream>usingnamespacestd;intmain(){ stringstr; chart; booljinwei=true; booltf; cin>>str>>t; if(str[0]=='0'&&t=='f'){ cout<<str; }elseif(str[0]=='1'&&t==&#......
  • 原码、反码、补码学习
    Java没有无符号数,所以首位都是符号位标志位0表示正数,1表示负数原码是数字的二进制表示,首位为符号位数字的表示用原码,计算用补码(因为计算机只有加法器,减法转换为加法)正数的原码=反码=补码(三码合一)负数反码=原码符号位不变,其余取反负数的补码=反码+10的补码=0000......
  • 原码, 反码, 补码
    原码,反码,补码原码:十进制数据的二进制表现形式,最左边是符号位,0为正,1为负.原码的弊端:1,利用原码进行计算的时候,如果是整数完全没有问题.2,但是如果是负数计算,结果就出错,实际运算的方向,跟正确的运算方向是相反的.反码出现的目的:为了解决原码不能计算负数......
  • 计算32位二进制整数中1的个数(包括负数补码)
    引言:在计算机科学和编程中,位操作是一项重要的技能。一个常见的任务是计算一个32位二进制整数中1的个数,包括负数的补码表示。这个问题有多种解决方法,本博客将介绍一种高效的解决方案,同时提供详细的代码案例。背景知识:在正整数的二进制表示中,1的个数表示了这个数的二进制形式中有多少......
  • 求一个整形整数原码中1的个数(不考虑溢出)
    intmain(){ unsignedinta=0; intcount=0; printf("请输入要求的整数>>:"); scanf("%d",&a); while(a) { if(a%2) { count++; } a=a/2; } printf("该数中二进制位为1的位数为%d",count); return0;}intmain(){......