C语言的有符号与无符号,二进制整数的扩展与截断
C语言的有符号与无符号,二进制整数的扩展与截断
前一节说了整数的表示方式,,也就是无符号编码与补码编码.这一届说一下二进制整数的扩展与截断,这部分内容与C语言挂钩.so,我们先看下面C语言的有符号和无符号数.
C语言中的有符号数和无符号数
有符号数和无符号数的本质差别事实上就是採用的编码不同,前者採用补码编码,后者採用无符号编码.
在C语言中,有符号数和无符号数是能够隐式转换的,不须要手动实施强制类型转换.只是也正是由于如此,可能你一不小心就将一个无符号数赋给了有符号数.就会造成出乎意料的结果,就像以下这样:
#include <stdio.h>
int main(){
short i = -12345;
unsigned short u = i;
printf("%d %d\n",i,u);
}
你自己观察一下输出结果你就会发现,一个负数变成了正数,再看以下这个程序,他展示了在进行关系运算时,因为有符号数和无符号数的隐式转换所导致的违背常规的结果.
#include <stdio.h>
void main(){
printf("%d\n",-1 < 0U);
printf("%d\n",-12345 < 12345U);
}
你自己看看输出结果,两个结果都是0,也就是false,这与我们直观的理解是违背的,原因就是由于在比較的过程中,有符号数被隐式的转换成了无符号数进行比較.
扩展
当我们将一个短整型的变量转换为整型变量时,就涉及到了位的扩展,此时由两个字节扩充为四个字节.
在进行位的扩展时,最easy想到的就是在高位所有补0,也就是将原来的二进制序列前面增加若干个0,也称为零扩展.另一种方式比較特别,是符号扩展,也就是针对有符号数的方式,他是直接扩展符号位,也就是将二进制序列的前面增加若干个最高位.
对于零扩展来说,非常明显扩展之后的值与原来的值是相等的,而对于符号扩展来说,则是一样,仅仅只是没有零扩展来的直观.我们在计算补码时有一个比較简单的办法,就是符号位若为0,则与无符号是类似的.若符号位为1,也就是负数时,能够将其余位取反终于再加1就可以.因此当我们对一个有符号的负数进行符号扩展时,前面增加若干个1,在取反之后都为0,因此依然会保持原有的数值.
总之,在对位进行扩展式,是不会改变原有数值的.
在书中对于负数的符号扩展还给出了这一过程的证明,事实上这个证明非常easy,就是利用了补码编码的公式而已.须要多提一点的是,这是使用了归纳法证明,因此这里仅仅是扩展了以为,详细步骤例如以下:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
截断
截断与扩展相反,它是将一个多维二进制序列截断为较少的位数,就是与扩展是相反的过程.
依据我们的直观推断也不难发现,截断可能会导致数据的丢失.对于无符号编码来说,截断后就是剩余位数的无符号编码数值.在书中给出了这一简单过程证明,它主要是想表明截断前后的数值的关系是取模所得到的.
对与补码编码来说,截断后的二进制序列与无符号编码是一样的,因此我们仅仅须要多加一步,将无符号编码转换为补码编码就好了.因此对于无符号编码和补码来说,能够得到下面两个公式.
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
其它语言中的有符号和无符号
从上面的分析能够看出,具有有符号和无符号的语言,可能引起一些不必要的麻烦,并且无符号数除了能表示的最大值更大以外,似乎没什么优点了.因此有非常多语言是不支持无符号数的.
我接触过的C#和JAVA就仅仅有有符号数,这样省去了非常多不必要的麻烦.无符号数非常多时候仅仅是为了表示一些无数值意义的标识,比方我们的内存地址,此时的无符号数有点类似数据库主键或者说键值对中的键值的概念,仅仅是一个标识而已.
小结
低位转高位叫扩展,高位转低位叫做截断.
C语言的有符号与无符号,二进制整数的扩展与截断的更多相关文章
- 深入理解计算机系统(2.4)---C语言的有符号与无符号、二进制整数的扩展与截断
开篇请各位猿友允许LZ啰嗦几句,最近一直在写计算机系统原理这系列文章,也已经下定决心要把这本书的内容写完.主要目的其实是为了巩固LZ的理解,另外也想把这些内容分享给猿友们,毕竟LZ觉得这些内容对程序猿 ...
- C语言进阶——有符号与无符号02
在计算机的内部,我们所有的信息都是由二进制数字组成的 有符号数的表实法: 在计算机内部用补码的方式表实有符号数 正数的补码位正数的本身 负数的补码为其绝对值取反然后加一得到 例如-7 他在计算机内部的 ...
- Java-java中的有符号,无符号操作以及DataInputStream
1. 无符号和有符号 计算机中用补码表示负数,并且有一定的计算方式:另外,用二进制的最高位表示符号,0表示正数.1表示负数.这种说法本身没错,可是要有一定的解释,不然它就是错的,至少不能解释,为什么字 ...
- int有符号和无符号类型内存 -- C
/* int 有符号 0xffffffff == -1 0xfffffffe == -2 最小 0x80000000 == -21 4748 3648 最大 0x7fffffff == 21 4748 ...
- java中有符号和无符号数据类型发生转换
package com.itheima.test01;/* * byte short int long float double 是有符号位的数 * char boolean 是无符号位的数 * 补码 ...
- 结构体位制 中存在 有符号 与 无符号 -- C
#include <stdio.h> #include <stdlib.h> #include <string.h> /* 有符号 结构体1 */ struct b ...
- char类型到底是有符号还是无符号
根据c标准,char类型到底是有符号整数类型还是无符号整数类型,这取决于c实现,也就是c编译器的作者的想法:( 那么,如何快速的编写一个检测程序,查看当前编译器如何对char进行定义? #includ ...
- 【 c语言中无符号和有符号的加法运算】【深入理解】--【sky原创】
原文:[ c语言中无符号和有符号的加法运算][深入理解]--[sky原创] 第一题 #include<stdio.h> int main() { unsigned int a=6; i ...
- ABAP语言实现 左移 <<、无符号右移 >>> 位移操作
这几天要在ABAP中实现 3DES 标准对称加密算法,与其他外部系统进行加密/解密操作.由于ABAP语言中没有 左移 <<.无符号右移 >>> 操作,只能自己实现 思路 ...
随机推荐
- nyoj--12--喷水装置(二)(区间覆盖问题+贪心)
喷水装置(二) 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水 ...
- 区间dp学习笔记
怎么办,膜你赛要挂惨了,下午我还在学区间\(dp\)! 不管怎么样,计划不能打乱\(4\)不\(4\).. 区间dp 模板 为啥我一开始就先弄模板呢?因为这东西看模板就能看懂... for(int i ...
- tomcat:Could not publish to the server. java.lang.IndexOutOfBoundsException
1.将工程加入到tomcat,报上述错误 2. run--maven build 报jar包错误: invalid LOC header (bad signature) 3.根据提示找到上述jar包, ...
- 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)
题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...
- append生成新变量的时候,没有如预期(It's a feature,not a bug?)
这是我在写一个项目中,遇到的一个golang的feature,如代码所示,我在for循环里,每次用append生成一个新的数组,(当然我以前一直以为可以这样,直到我在stackoverflow上发现不 ...
- js文字的无缝滚动(上下)
使用scrolltop值的递增配合setInterval与setTimeout实现相关效果,左右无缝滚动使用scrollLeft即可 Dom内容 <div id="container& ...
- [HAOI2016]找相同字符 广义后缀自动机_统计出现次数
题目描述:给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. 输入输出格式输入格式:两行,两个字符串 s1,s2,长度分别为n ...
- LNMP安装部署开源IP管理工具phpipam
1.数据库 mariadb 安装 //依赖安装 yum install -y apr* autoconf automake bison bzip2 bzip2* compat* \ cpp curl ...
- python etree.HTML
1.编码问题(编码参数 parser): resp_html = etree.HTML(res,parser=etree.HTMLParser(encoding='gbk')) 2.大小写问题(大写转 ...
- centos的终端字体杂乱的问题
sudo yum -y install dejavu-sans-* dejavu-serif-fonts 下载字体一下就好了