深入理解计算机系统(2.4)---C语言的有符号与无符号、二进制整数的扩展与截断
开篇请各位猿友允许LZ啰嗦几句,最近一直在写计算机系统原理这系列文章,也已经下定决心要把这本书的内容写完。主要目的其实是为了巩固LZ的理解,另外也想把这些内容分享给猿友们,毕竟LZ觉得这些内容对程序猿的实力还是有着很大的潜在提高的。
只是这种原理性的文章写起来相对复杂与繁琐,较对起来也比较困难,因为文章里充斥着各种各样的数学符号,不过相对于这样的写作难度来说,其受欢迎程度,却远远比不上一些难度较低的杂文。这一点从LZ的博客就能很明显的看出,LZ博客排名前几的文章,几乎全部都是LZ写的一些杂谈,比如经历、建议、感悟等等这一类的。
不过LZ也很理解这种现象,毕竟杂文看起来不怎么需要动脑子,内容相对来说也比较有趣,而且说不定偶尔也能有意外的大收获,受欢迎自是无可厚非的。不过对于计算机系统原理这种文章来说,倘若各位猿友能够坚持看下去的话,应该是会有不少的收获的。
此外LZ也希望各位猿友在观看之余,也不妨给予LZ一些鼓励和支持,这样不仅LZ的动力会大大增加,也会由于猿友们的鼓励而产生更大的责任感,从而更加费心的将内容更简单的解释清楚。
废话就到此结束吧,再写下去的话估计有猿友要忍不住吐槽LZ废话连篇了。就此打住,其实说了这么多,LZ就是想说五个字,“点个推荐吧。”
引言
在上一章中,我们着重介绍了整数的表示方式,也就是无符号编码和补码编码。本次我们来看一下二进制整数的扩展与截断,这部分内容是与C语言挂钩介绍的。因此我们首先来简单的看一下C语言的有符号数和无符号数。
C语言中的有符号数和无符号数
有符号数和无符号数的本质区别其实就是采用的编码不同,前者采用补码编码,后者采用无符号编码。
在C语言中,有符号数和无符号数是可以隐式转换的,不需要手动实施强制类型转换。不过也正是因为如此,可能你不小心将一个无符号数赋给了有符号数,就会造成出乎意料的结果,就像下面这样。
#include <stdio.h> int main(){
short i = -;
unsigned short u = i;
printf("%d %d\n",i,u);
}
结果如下。
一个不小心,一个负数就变成正数了,再看下面这个程序,它展示了在进行关系运算时,由于有符号数和无符号数的隐式转换所导致的违背常规的结果。
#include <stdio.h> int main(){
printf("%d\n",- < 0U);
printf("%d\n",- < 12345U);
}
结果如下。
可以看到,两个结果都为0,也就是false,这与我们直观的理解是违背的,原因就是因为在比较的过程中,有符号数被隐式的转换成了无符号数进行比较。
扩展
当我们将一个短整型的变量转换为整型变量时,就涉及到了位的扩展,此时由两个字节扩充为四个字节。
在进行位的扩展时,最容易想到的就是在高位全部补0,也就是将原来的二进制序列前面加入若干个0,也称为零扩展。还有一种方式比较特别,是符号扩展,也就是针对有符号数的方式,它是直接扩展符号位,也就是将二进制序列的前面加入若干个最高位。
对于零扩展来说,很明显扩展之后的值与原来的值是相等的,而对于符号扩展来说,则是一样,只不过没有零扩展来的直观。我们在计算补码时有一个比较简单的办法,就是符号位若为0,则与无符号是类似的。若符号位为1,也就是负数时,可以将其余位取反最终再加1即可。因此当我们对一个有符号的负数进行符号扩展时,前面加入若干个1,在取反之后都为0,因此依旧会保持原有的数值。
总之,在对位进行扩展时,是不会改变原有数值的。
在书中对于负数的符号扩展还给出了这一过程的证明,LZ这里就不多做叙述了,其实这个证明很简单,就是利用了补码编码的公式而已。需要多提一句的是,这里使用了归纳法证明,因此这里只是扩展了一位,具体过程如下。
截断
截断与扩展相反,它是将一个多位二进制序列截断至较少的位数,也就是与扩展是相反的过程。
根据我们的直观判断也不难发现,截断可能会导致数据的失真。对于无符号编码来说,截断后就是剩余位数的无符号编码数值。在书中给出了这一简单过程的证明,它主要是想表明截断前与截断后的数值的关系是取模所得到的。
对于补码编码来说,截断后的二进制序列与无符号编码是一样的,因此我们只需要多加一步,将无符号编码转换为补码编码就可以了。
因此对于无符号编码和补码来说,可以得到以下两个公式。
其它语言中的有符号与无符号
从上面的分析不难看出,具有有符号和无符号数的语言,可能会因此引起一些不必要的麻烦,而且无符号数除了能表示的最大值更大以外,似乎并没有太大的好处。因此有很多语言是不支持无符号数的。
比如LZ所使用的Java语言,就只有有符号数,这样省去了很多不必要的麻烦。无符号数很多时候只是为了表示一些无数值意义的标识,比如我们的内存地址,此时的无符号数就有点类似于数据库主键或者说键值对中的键值的概念,仅仅是一个标识而已。
文章小结
本文主要阐述了C语言当中的有符号数和无符号数,以及低位转高位的扩展、高位转低位的截断运算,下一章我们将讲解很重要的一节内容,整数的二进制运算。
深入理解计算机系统(2.4)---C语言的有符号与无符号、二进制整数的扩展与截断的更多相关文章
- C语言的有符号与无符号,二进制整数的扩展与截断
C语言的有符号与无符号,二进制整数的扩展与截断 前一节说了整数的表示方式,,也就是无符号编码与补码编码.这一届说一下二进制整数的扩展与截断,这部分内容与C语言挂钩.so,我们先看下面C语言的有符号和无 ...
- C语言进阶——有符号与无符号02
在计算机的内部,我们所有的信息都是由二进制数字组成的 有符号数的表实法: 在计算机内部用补码的方式表实有符号数 正数的补码位正数的本身 负数的补码为其绝对值取反然后加一得到 例如-7 他在计算机内部的 ...
- 深入理解计算机系统(2.5)------C语言中的有符号数和无符号数以及扩展和截断数字
上一篇博客我们讲解了计算机中整数的表示,包括无符号编码和补码编码,以及它们之间的互相转换,个人觉得那是非常重要的知识要点.这篇博客我们将介绍C语言中的有符号数和无符号数以及扩展和截断数字. 1.C语言 ...
- CSAPP(深入理解计算机系统)读后感
9月到10月8号,包括国庆七天,大概每天5小时以上的时间,把Computer System: A Programmer Perspective 2rd version(深入理解计算机系统)的英文版啃完 ...
- 【 c语言中无符号和有符号的加法运算】【深入理解】--【sky原创】
原文:[ c语言中无符号和有符号的加法运算][深入理解]--[sky原创] 第一题 #include<stdio.h> int main() { unsigned int a=6; i ...
- Ch2信息的表示和处理——caspp深入理解计算机系统
目录 第2章 信息的表示和处理 2.1 信息存储 2.1.1 十六进制 一.表示法 二.加减 三.进制转换 2.1.2 字 2.1.3 数据大小 2.1.4 字节顺序与表示 一.字节的排列规则 二.打 ...
- ABAP语言实现 左移 <<、无符号右移 >>> 位移操作
这几天要在ABAP中实现 3DES 标准对称加密算法,与其他外部系统进行加密/解密操作.由于ABAP语言中没有 左移 <<.无符号右移 >>> 操作,只能自己实现 思路 ...
- 深入理解计算机系统(4.1)---X86的孪生兄弟,Y86指令体系结构
引言 各位猿友们好,计算机系统系列很久没更新了,实在是抱歉之极.新的一年,为了给计算机系统系列添加一些新的元素,LZ将其更改为书的原名<深入理解计算机系统>.这本书非常厚,而且难度较高,L ...
- 《深入理解计算机系统》 Chapter 7 读书笔记
<深入理解计算机系统>Chapter 7 读书笔记 链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(货被拷贝)到存储器并执行. 链接的时机 编译时,也就是 ...
随机推荐
- 将一列包含多个ID拆分多行
看到个不常见的问题~然后在 Inner Sql Server2008 里面找到一个思路. 如果下面的表结构,如何拆分多行并对应员工号呢? 首先创建测试表 CREATE TABLE Department ...
- W3School-CSS测验
The only way to survive was to enjoy the good moments and not dwell too much on the bad. 生活,就应该享受美好的 ...
- 错误“Unexpected namespace prefix "xmlns" found for tag LinearLayout”的解决方法(转)
(转自:http://blog.csdn.net/bombzhang/article/details/12676789) 有一次升级开发工具后发现xml脚本出现错误“Unexpected namesp ...
- IE6-11使用location.href提交时的链接复制到firefox或chrome时出现乱码
这是在开发国际机票查询页时碰到的一个问题,测试工程师在IE里执行查询操作,然后把查询的url赋值到firefox的地址栏,firefox打开后就变成乱码了. 1. IE浏览器,选择出发地,出发日期等后 ...
- HttpURLConnection用法详解
针对JDK中的URLConnection连接Servlet的问题,网上有虽然有所涉及,但是只是说明了某一个或几个问题,是以FAQ的方式来解决的,而且比较零散,现在对这个类的使用就本人在项目中的使用经验 ...
- 分享——张南《从Desktop到Mobile的自动化测试实践》
张南在top100summit(14年)上分享了google从Desktop到Mobile的自动化测试实践,这里分享一下 案例简述 随着每年移动用户量的增长,移动网络速度以及覆盖力的增强,移动设备逐年 ...
- Flex4 vs Flex3: Repeater vs DataGroup
repeaters太老土了!如果你过去使用过它,你会发出这种感概.现在,我们终于要摆脱它了.Repeaters不仅有沉重的组件,而且接合使用很不方便.那么,Flex 4中有什么可以帮助我们吗?Data ...
- 嵌入式Linux 修改启动LOGO
1.嵌入式 Linux LOGO显示原理 嵌入式Linux是直接在FrameBuffer的基础上.直接显示一个ppm格式的图象. 它 kernel/drivers/video/fbc ...
- 收集入侵Windows系统的证据
随着网络的不断扩大,网络安全更加会成为人们的一个焦点,同时也成为是否能进一步投入到更深更广领域的一个基石.当然网络的安全也是一个动态的概念,世界上没有绝对安全的网络,只有相对安全的网络.相对安全环境的 ...
- net对XML增删改查
Pass:看公司代码,配置下拉框的功能,和下拉框的数字转文字.配置xml里面有下拉的value,name,这样界面直接显示数字,然后转译成中文 1.xml文件格式 <?xml version=& ...