本人研究不深,如有错误请不吝赐教!!

先来个最基本的介绍

参考:
https://blog.csdn.net/jdq8576/article/details/82425265
百度百科:https://baike.baidu.com/item/补码

源码&&反码&&补码&&二进制十进制小数部分的转化





1.正数的补码表示
正数的补码 = 原码

负数的补码 = {原码符号位不变} + {数值位按位取反后+1} or

 = {原码符号位不变} + {数值位从右边数第一个1及其右边的0保持不变,左边安位取反}

以十进制整数+97和-97为例:

+97原码 = 0110_0001b

+97补码 = 0110_0001b

-97原码 = 1110_0001b

-97补码 = 1001_1111b

2.纯小数的原码
纯小数的原码如何得到呢?方法有很多,在这里提供一种较为便于笔算的方法。

以0.64为例,通过查阅可知其原码为0.1010_0011_1101_0111b。
操作方法:

将0.64 * 2^n 得到X,其中n为预保留的小数点后位数(即认为n为小数之后的小数不重要),X为乘法结果的整数部分。

此处将n取16,得

X = 41943d = 1010_0011_1101_0111b

即0.64的二进制表示在左移了16位后为1010_0011_1101_0111b,因此可以认为0.64d = 0.1010_0011_1101_0111b 与查询结果一致。

再实验n取12,得

X = 2621d = 1010_0011_1101b 即 0.64d = 0.1010_0011_1101b,在忽略12位小数之后的位数情况下,计算结果相同。

3.纯小数的补码
纯小数的补码遵循的规则是:在得到小数的源码后,小数点前1位表示符号,从最低(右)位起,找到第一个“1”照写,之后“见1写0,见0写1”。

以-0.64为例,其原码为1.1010_0011_1101_0111b

则补码为:1.0101_1100_0010_1001b

当然在硬件语言如verilog中二进制表示时不可能带有小数点(事实上不知道哪里可以带小数点)。

4.一般带小数的补码
一般来说这种情况下先转为整数运算比较方便。小数的补码,一般在计算机中适当做浮点数处理的,如果非要想要求补码,那就只能当做定点数求补码了,也就是定点小数(在不支持浮点运算的硬件电路里)。

-97.64为例,经查询其原码为1110_0001.1010_0011_1101_0111b

笔算过程:

-97.64 * 2^16 = -6398935 = 1110_0001_1010_0011_1101_0111b,其中小数点在右数第16位,与查询结果一致。

则其补码为1001_1110_0101_1100_0010_1001b,在此采用 负数的补码 = {原码符号位不变} + {数值位按位取反后+1} 方法

5.补码得到原码
方法:符号位不动,幅度值取反+1 or符号位不动,幅度值-1取反

-97.64补码 = 1001_1110(.)0101_1100_0010_1001b

取反 = 1110_0001(.)1010_0011_1101_0110b

+1 = 1110_0001(.)1010_0011_1101_0111b 与查询结果一致

6.补码的拓展
在运算时必要时要对二进制补码进行数位拓展,此时应将符号位向前拓展。

-5补码 = 4’b1011 = 6’b11_1011

ps.原码的拓展是将符号位提到最前面,然后在拓展位上部0.

-5原码 = 4‘b’1101 = 6’b10_0101,对其求补码得6’b11_1011,与上文一致。


补码求真值

已知一个数的补码,求真值: 如果是负数的话,先将该补码数值部分按位取反再加1,求出这个二进制代表的十进制数,然后加个负号就行了,如果是正数的话,这个二进制数代表的十进制就是真值。
例如:100 的真值: 00----->11 11+01=100 所以真值为-4
这个例子比较特殊,这个负数的补码与原码(真值)一样。。

所以说,补码到真值转换有两种转换方法,它的解释可以有有时钟来解释。


最后来谈谈小数/纯小数的补码问题。

求纯小数的原码、反码、补码

注意这里是纯小数,也就是-1到+1之间的小数,对于定点数表征的话,位宽全部用来存放小数位。。


了解规则后再细看。

【补码表示】为什么定点小数的-1补码表示为1.0000以及补码表示范围问题

首先了解一下原码,反码,补码的概念

原码

原码的表示方法:


简单来说就是,在机器中我们使用0和1来区分一个数的符号,用0来表示正数,用1来表示负数。而原码表示就是将一个数绝对值的二进制表示出来后根据是正数还是负数在前面加0或1表示数的符号。这里注意一点,在定点小数中,原码是不能表示出-1这个值的

反码

反码的表示方法


简单易懂一些的话其实就是如果是正数,X的反码就等于原码,如果是负数,将X的数值位全部取反

补码

对求一个数的补码有一个简单的口诀,若X是正数,则X的补码等于原码,若X是负数,X的补码就是在求出原码的基础上数值位全部取反后在最后一位加1。

机器数表示范围

https://blog.csdn.net/m0_37454852/article/details/78076027

以n位机器码为例。

  1. 原码:
      有符号整数:[-(2^n-1), 2^n-1];
      有符号小数:[-(1-2^(-n)), 1-2^(-n)];
  2. 反码的表示范围和原码相同
  3. 补码
      有符号整数:[-2^n, 2^n-1];
      有符号小数:[-1, 1-2^(-n)];

从上我们可以看出,有符号数的补码要比原码和反码多表示出一位来,那么究竟是为什么呢?

补码比原码、反码多出一位的原因:
  以8位机器码表示的有符号整数为例,它可以表示的原码和反码范围是[-127, 127],而可以表示的补码范围是[-128, 127]。
  原码和反码的±0是不同的表示方法,即:
    +0:00000000
    -0 :10000000
  而反码的±0都是同一个表示方法,同样以8位机器码为例:
    ±0 :00000000
  因此补码中便多出了一个<10000000>,可以用来表示其他的数,此处即可以表示真值为-128。在最位的1,既表示负号、又表示数值位。


https://blog.csdn.net/qq_39690706/article/details/85856792
根据上面的定义可以知道,原码和反码对于0有两种表示方法
原码中
[+0] = 0.0000,[-0] = 1.0000
反码中
[+0] = 0.0000,[-0] = 1.1111
补码中
[+0]=[-0]=0.0000
这里可以知道,在表示数据的时候,补码比原码少了一个-0,而由于表示数据所用的位数是一样的,也就是能表示的整数的个数不会变,所以补码会比原码和补码多表示一个数

对于定点整数

设位数一共为8位
原码表示范围为 -127-127,即1111 1111~0111 1111
反码表示范围为 -127-127,即1000 0000~0111 1111
补码表示范围为 -128-127,即1000 0000~0111 1111
我们可以尝试求一下-128的原码,但可以发现7位二进制表示不出来,必须得用8位二进制表示,但这样符号位就被占用了。但由于上面说的补码比原码和补码少一个0的表示方法,这就让补码多了一个10000000来表示其他的数,这里具体的细节我也不是很懂@_@,但可以这样记吧,-1到-127已经有对应的原码和补码了,所以也会有对应的补码,而10000000首位是1代表负数,不能和其他数的表示起冲突所以就是-128了。由此,补码可以表示128个负数,1个0以及127个负数共256个数

对于定点小数

还是设位数一共8位
原码表示范围为1.111 1111 ~0.111 1111,即-127/128到127/128
反码表示范围为1.000 0000~0.111 1111,即-127/128到127/128
补码表示范围为1.000 0000~0.111 1111,即-1到127/128
在这里原码和反码都好理解,就是补码会有一个问题,为什么补码会有一个1.000 0000而且居然对应的值是-1,也就是说如果小数用补码表示的话最小值是-1。这里如果用一开始说的取反加一你会发现根本不是这个值。之后才知道取反加一靠的是原码,但看前面原码的定义公式你会发现原码根本表示不了定点小数-1,原码所能表示的是定点整数-1,定点小数-1这里严谨一点的话其实是-1.0。
这里要求定点小数-1.0的补码的话就要用到上面的补码定义公式了(要不然我怎么会贴hhh),由公式可知,-1.0的补码为2+X = 2-1.0 = 1.000 0000
当然也有这样的理解

总结:由于补码表示0的唯一性,补码比原码少一个-0的表示,多一个-1的表示以及负整数表示范围多了一个-128
PS:主要是把自己最近碰到的问题写一下让自己记牢一些。其实如果把上面贴的几个公式吃透的话这些问题根本不会有的orz,注意对比原码反码补码边界的取值你会发现其实说的就是这些东西orz

参考:
http://bbs.kaoyan.com/t2806127p1


当然这里也有两个论坛,发现老是那些人在问,以及在回答这些问题。。

论坛1:

https://ask.csdn.net/questions/211705

正负小数的补码怎样求
正负小数的补码怎样求?
和整数的规律一样吗,也是正小数不变负小数求反加一么
求举例

网友1:

那看定点数还是浮点数,
浮点数是用阶码,尾数等表示的,和补码没什么关系。
定点数只能表示纯小数,也就是0.xxx这样的数,它的补码是把小数部分xxx取补就好了(就是整数不变,负数取反加一),当然带上符号位。

网友2:
纯小数补码

若真值为纯小数,它的补码形式为,Xs.X1X2X3X4X5Xn,其中Xs表示符号位,补码的定义为:【X】补=X(0<=X<1)或2+X=2-/X/(-1<=X<0)(MOD=2)
纯小数在求它的原码、反码、和补码时方法和整数是一样的。
例如:X=-0.1011 系统要是规定为8位,那么它的原码为
[x]原=1.1011000 [x]反=1.0100111 [x]补=1.0101000
也就是说系统规定为8位,当位数不够的时候,要在最低有效数后面用0补齐,然后再求它的原码、反码、和补码。正小数也是按照这个方法。

论坛2:

https://bbs.csdn.net/topics/390379095

在定点小数中,为什么-1的补码为:1.0000?
网友1:
定点小数中没有-1,只有-1.0

网友2:

二进制小数 原码对应十进制值 补码对应十进制值
0.00        0                0
0.01        0.25             0.25
0.10        0.5              0.5
0.11        0.75             0.75
1.00        1               -1
1.01        1.25            -0.75
1.10        1.5             -0.5
1.11        1.75            -0.25

网友3:
大神,你这里的二进制小数,最高位是符号位吗?如果是,
1.00(B) == -1(D)怎么算的?

最高位是符号位,0表示正数,1表示负数
求某个补码表示的负数对应的绝对值的步骤为:
各位取反,末位加1
1.00→各位取反→0.11→末位加1→1.00

想要了解更多,可以参见我另外一篇博客:
https://blog.csdn.net/edward_zcl/article/details/89439128
以及:
https://blog.csdn.net/AaricYang/article/details/87882868
https://blog.csdn.net/ferrarild/article/details/7050781

本文参考自:
https://blog.csdn.net/qq_39690706/article/details/85856792
https://blog.csdn.net/Anliya/article/details/5345741
https://blog.csdn.net/jdq8576/article/details/82425265
https://blog.csdn.net/qq_40816078/article/details/82689492
https://blog.csdn.net/moon9999/article/details/57130068

二进制数的补码及运算相关推荐

  1. 二进制数的补码及运算(1)

    本人研究不深,如有错误请不吝赐教!! 1.正数的补码表示 正数的补码 = 原码 负数的补码 = {原码符号位不变} + {数值位按位取反后+1}    or = {原码符号位不变} + {数值位从右边 ...

  2. 二进制数的补码及运算(2)

    本章均对整数进行操作,小数情况请先转化为整数并对其符号位. 使用如下数据: 1.加法 正数+正数 正数+负数 负数+负数 通过计算可以发现,补码的加法运算可以直接相加,但在有时会产生进位,因此在编写硬 ...

  3. 定点补码加减法运算_计算机相关问题:谈谈我眼中的补码

    导读:补码是如何产生的.计算机如何表示负数. 1.前提认知 (1)计算机中只有加法器,加减法使用的都是加法器,同时计算机通过加法器左移累加实现乘法运算.右移累减实现除法运算. (2)补码是一种编码格式 ...

  4. 原码、反码、补码及其运算

    原码.反码.补码及其运算 一.补码举例说明 二.原码.反码.补码的运算 计算机中的数据都是以补码的形式存放和计算的,所以要弄明白到底什么是补码? 一.补码举例说明 假设现在是5点钟,但表却显示10点钟 ...

  5. 原码、反码、补码的运算 【2分钟掌握】

    最近在学计算机组成原理,又遇到了原码.反码.补码的运算. 就整理了运算规则,方便以后复看,减少时间浪费. 简介 原码:符号位 + 数值位 反码:反码是原码和补码之间转化的工具,是个桥梁作用. 补码:补 ...

  6. c或c++语言什么时候用补码来运算,C/C++(基础编码-补码详解)

    两个数的交换 1.引入第三者. 2.求和运算,求差.(这样会产生内存溢出) 3.异或运算 a = a^b; b = a^b; a = a^b; 8b(bit位) = 1B(Byte=字节)//最小单位 ...

  7. 创建带头结点单链表实现二进制数加1的运算

    题目描述: 建立一个带头结点的线性链表,用以存放输入的二进制数,链表中每个结点的data域存放一个二进制位.在此链表上实现对二进制数加1的运算,并输出运算结果. 测试数据1: 1010011 测试数据 ...

  8. 用链表实现对二进制数加1的运算

    题目描述: 建立一个带头结点的线性链表,用以存放输入的二进制数,链表中每个结点的data域存放一个二进制位.并在此链表上实现对二进制数加1的运算. 问题分析: ①建链表:二进制数可用带头结点的单链表存 ...

  9. 建立一个带头结点的线性链表,用以存放输入的二进制数,链表的每一个节点的data域存放一个二进制位。并在此链表上实现对二进制数加1的运算;

    1.题目:建立一个带头结点的线性链表,用以存放输入的二进制数,链表的每一个节点的data域存放一个二进制位.并在此链表上实现对二进制数加1的运算: 部分函数调用参考:https://blog.csdn ...

最新文章

  1. [新手学Go]GO语言闭包的使用
  2. dojo中的AMD模式开发案例
  3. .val()数据乱码_【目标检测数据集】PASCAL VOC制作
  4. 《团队激励与沟通》第 7 讲——团队合作概述 重点部分总结
  5. Tensorflow实现数据分档操作
  6. VB SendMessage向其他程序窗口发送字符串消息实例
  7. 兼容所有浏览器的省略号--纯CSS策略
  8. Java中使用各种方式实现网页跳转
  9. linux java不能运行命令,linux java不能运行命令
  10. 【nexys3】【verilog】小设计——拆弹游戏
  11. 标准资本赵晨:Token会推动金融市场的流动性|筱静观察
  12. 阿里巴巴离职DBA职业生涯总结
  13. WAV音频信号文件的相关知识
  14. goldenboy机器人_急求阿西莫夫机器人,基地,帝国三大系列的书名及其简介
  15. 生产者和消费者。举一个寄信的例子
  16. DataWhale NLP组队学习 Task5 基于深度学习的文本分类2
  17. 服务器系统2012r2升级专业版,Windows Server 2012 R2版本区别
  18. 关于为什么定积分的计算要用到原函数
  19. 什么是 msvcp120.dll 错误消息?
  20. 春暖花开--2013年度总结

热门文章

  1. java二维数组添加数据_Java自学路线图
  2. 计算机管理映像路径,手把手教你解决win7系统任务管理器显示映像路径的恢复办法...
  3. PHP实现RSA算法
  4. Github上开源项目readme里好看的高大上的有趣的徽章从何而来
  5. c语言钻石字母图案,PS制作排列组合闪亮钻石文字图片
  6. python爬虫爬取网页内容
  7. 【渝粤题库】陕西师范大学202491 法语(一)作业
  8. 参考文献的类型--参考文献里的J、M等字母都代表什么
  9. 【STM32】HAL库 ——DAC
  10. Android 跳转外部浏览器坑