1、背景介绍

(1)表达式中符号选取,具有贪心特性,即从左到右,尽量多的匹配符号;

(2)C语言的表达式中,存在隐式类型转换,基本原则为向大数转换,具体说明如下:

  • 占用字节数少的类型,向占用字节数多的类型转换;
  • 占用字节数相同情况下,有符号向无符号转换
  • 整数类型向浮点类型转换;
  • 单精度向双精度转换;
  • Char型是否有符号取决于编译器,在运算时会提升为int;

2、无符号数与有符号数的转化过程分析

原理:计算机中的数据,均以二进制方式存储,并且以二进制补码形式存储。;类型转换时,内存中存储的数据位值不变,编译器根据类型改变解释方式。

最高位为符号位,符号位为0时表示正数,符号位为1时表示负数;

存储数值解释为补码,根据符号位决定补码的转换规则,正数的原码、反码、补码相同,负数需要将补码转换成原码(减一取反),获得真值。

示例(4位字长):内部存储为1010
无符号数: 表示数值10。
有符号数:符号位为1,表示负数;存储值为补码,将其转化原码1110,表示数值-6。

3、原码、反码、补码

机器数与真值

(1)机器数
将符号数字化的数,即数字在计算机中的二进制表示形式(仅为表示形式,不是数值在内存中真实二进制存储内容,后文将说明,数据以补码形式实际存储)。

  • 特点1:符号数字化。
    二进制数的最高位,称符号位,0表示正号,1表示负号。
  • 特点2:位数受物理设备的限制。
    机器内部运算单元一次能表示的二进制位数叫做机器的字长,一台机器的字长是固定的,由运算器(冯诺依曼结构)的寄存器长度决定。通常说的,32位系统或者64位系统,即表明该系统的字长为32位或64位。8位(bit)字长又叫做一个字节(Byte)。

(2)真值
用“+”和“-”来表示正负号的二进制数叫做符号数的真值。
机器数是数字在机器内部的表示形式,真值是利用数学符号表达的二进制数值。
如:“00001101”和“10001101”是两个机器数(字长八位),其真值分别为+0001101和-0001101。

原码、反码、补码

(1)原码
机器数表示法,最高位表示符号位,其他位存放数值(真值)的绝对值。

原码可以直观地表示数字的数值大小,但是使用原码进行加减法时需要对符号位进行判断,电路设计复杂。为了简化电路设计和运算逻辑,通过引入反码和补码,将减法转换成负数的加法。正数的原码、反码、补码均相同。
如,机器数“00001 101”和“1000 1101”的原码为0000 1101和1000 1101。

(2)反码
正数的反码与原码形式相同;负数的反码,最高位表示符号位,其他位为真值的绝对值取反,即对原码的数值为按位取反。

如,机器数“00001101”和“10001101”的原码为0000 1101和1000 1101,反码为00001101和1111 0010。

(3)补码

正数的补码与原码形式相同;负数的补码,表现为反码加一。

负数补码的快速计算方法:符号位不变,用模值减去补码二进制的数值位,即可得到负数的补码。“补齐”的是该负数的绝对值与模值之间的距离。
如,计算4字长场景下,原码1011的补码:
通常方法(对原码取反加一):[1011]原 = [1100]反 = [1101]补码
快速方法(有效模值 – 原码的数值绝对值):4字长机器,最高位表示符号位,实际有效模值为为2^3,即1000;原码数值部分绝对值011;
有效模值-原码的数值部分绝对值 = 1000 – 011 = 101,加上符号位,则其补码为1101。

补码的理解与应用

(1)理解分析
补码的引入来源于“同余定理”。数学上,两个整数除以同一个整数,若得相同余数,则说两个整数同余。
数学定义如下:两个整数a、b,若它们除以整数m所得的余数相等,则称a与b对于模m同余,记作:a≡b (mod m)。
显然,若a与b对于模M同余,(a+M)与b对模M也同余。

在运算器进行加减法时,寄存器的溢出特性类似于取余操作,寄存器表达的最大数字即为 模 – 1。

假设寄存器位数为n,则模为2^n,记为M,且有正值A和负值-B(B为其绝对值),
(A – B) (mod M)= (A + (-B) + M)(mod M) = (A + (M – B))(mod M) = (A + (-B)补)(mod M)
显然,(-B)补=M-B,即(-B)的补码为模值M减去(-B)真值的绝对值。
可见,在模为M的条件下,A减去B,可以用A加上-B的补码来实现。

(2)反码与补码的关系推导
假设机器字长为n,负数K, 模2^(n-1),
将符号位参与运算,原码与反码的最高位相同,进位后溢出丢弃,有
[K]原 + [K]反 = 2^(n – 1) – 1 (1)

由补码定义,可知
[K]补 = 2^(n) – [K]真值绝对值 (2)

结合(1)、(2)有,
[K]补 – [K]反 = 1 + 2^(n-1) + [K]原 – [K]真值绝对值 (3)

上式的后三项结合后,产生进位,溢出后丢弃,移项可得
[K]补 = [K]反 + 1 (4)

结论:负数补码的计算口诀“取反加一”,仅是有与补码性质与反码性质的“巧合”,通过寄存器的溢出特性更容器理解补码的构造思路。

(3)应用分析
补码引入,可以将加减法统一成加法,并将符号位同时参与运算,不需要要进行判断,极大地简化了电路。以4位字长运算,举例如下:
例1:7 – 5
7的原码、反码、补码相同,为0111。
-5的原码为1101,反码为1010,补码为1011。
在内存中,数据的存储是以补码的形式进行真实存放的,则在加法运算器中,最高位进位后丢弃
7 – 5 = [7]补码 + [-5]补码 = 0111 + 1011 = 1(进位丢弃) 0010 = 2

例2:-2 – 4
-2的原码为1010,反码为1101,补码为1110;
-4的原码为1100,反码为1011,补码为1100;

-2-4 = [-2]补码 + [-4]补码 = 1110 + 1100 = 1(进位丢弃) 1010

运算后的存储结果为1010,此时数据仍是补码形式,求其真值需要先转化成原码,利用“减一取反”的逆向过程求补码的原码,可得[1010]补 = [1100]原 = -6。

原文地址:http://www.cnblogs.com/HZL2017/p/16828426.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性