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语言的有符号与无符号,二进制整数的扩展与截断的更多相关文章

  1. 深入理解计算机系统(2.4)---C语言的有符号与无符号、二进制整数的扩展与截断

    开篇请各位猿友允许LZ啰嗦几句,最近一直在写计算机系统原理这系列文章,也已经下定决心要把这本书的内容写完.主要目的其实是为了巩固LZ的理解,另外也想把这些内容分享给猿友们,毕竟LZ觉得这些内容对程序猿 ...

  2. C语言进阶——有符号与无符号02

    在计算机的内部,我们所有的信息都是由二进制数字组成的 有符号数的表实法: 在计算机内部用补码的方式表实有符号数 正数的补码位正数的本身 负数的补码为其绝对值取反然后加一得到 例如-7 他在计算机内部的 ...

  3. Java-java中的有符号,无符号操作以及DataInputStream

    1. 无符号和有符号 计算机中用补码表示负数,并且有一定的计算方式:另外,用二进制的最高位表示符号,0表示正数.1表示负数.这种说法本身没错,可是要有一定的解释,不然它就是错的,至少不能解释,为什么字 ...

  4. int有符号和无符号类型内存 -- C

    /* int 有符号 0xffffffff == -1 0xfffffffe == -2 最小 0x80000000 == -21 4748 3648 最大 0x7fffffff == 21 4748 ...

  5. java中有符号和无符号数据类型发生转换

    package com.itheima.test01;/* * byte short int long float double 是有符号位的数 * char boolean 是无符号位的数 * 补码 ...

  6. 结构体位制 中存在 有符号 与 无符号 -- C

    #include <stdio.h> #include <stdlib.h> #include <string.h> /* 有符号 结构体1 */ struct b ...

  7. char类型到底是有符号还是无符号

    根据c标准,char类型到底是有符号整数类型还是无符号整数类型,这取决于c实现,也就是c编译器的作者的想法:( 那么,如何快速的编写一个检测程序,查看当前编译器如何对char进行定义? #includ ...

  8. 【 c语言中无符号和有符号的加法运算】【深入理解】--【sky原创】

    原文:[ c语言中无符号和有符号的加法运算][深入理解]--[sky原创]   第一题 #include<stdio.h> int main() { unsigned int a=6; i ...

  9. ABAP语言实现 左移 <<、无符号右移 >>> 位移操作

    这几天要在ABAP中实现 3DES 标准对称加密算法,与其他外部系统进行加密/解密操作.由于ABAP语言中没有 左移 <<.无符号右移 >>>  操作,只能自己实现 思路 ...

随机推荐

  1. 20.计算速度最快的valarray

    #include <string> #include <iostream> //用于计算,计算的性能高于vector与array #include <valarray&g ...

  2. 使用与不适用@RequestBody注解的区别

    1. 如果使用@RequestBody接受页面参数: public Map<String,Object> insertBudget(@ApiParam(required = true,na ...

  3. Asp.Net中使用水晶报表(中)

    Asp.Net中使用水晶报表(中) 使用Pull模式 我们将通过下面的这些步骤来通过Pull模式来执行水晶报表 1.首先创建rpt文件,并使用水晶报表设计接口设置一些必须的数据连接. 2.拖放一个 C ...

  4. 写给自己的Java程序员学习路线图_转载

    如下是我做开发这三年经常使用一些技术和工具,当然这些技术也都是需要加强的(有些是我一直使用的,不过不深入,有些内部的原理等等不是很清楚) 前端部分: 1)HTML:网页的核心语言,构成网页的基础 2) ...

  5. pandas学习系列(一):时间序列

    最近参加了天池的一个机场航空人流量预测大赛,需要用时间序列来预测,因此开始使用python的pandas库 发现pandas库功能的确很强大,因此在这记录我的pandas学习之路. # -*- cod ...

  6. 洛谷1525 关押罪犯NOIP2010 并查集

    问题描述 S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示某两 ...

  7. centeros安装jdk

    准备工作: java se下载网址:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.ht ...

  8. ECNUOJ 2143 端午节快乐

    端午节快乐 Time Limit:1000MS Memory Limit:65536KBTotal Submit:1720 Accepted:868 Description  有一段有趣的传说.公元前 ...

  9. eclipse 启动报错has value '1.7', but '1.8' is required

    由于安装elasticsearch5.x版本时需要jdk8,所以在本机安装了,不过后来发现启动eclipse时报错: Error: Registry key 'Software\JavaSoft\Ja ...

  10. select &amp; epoll

    同步.异步.堵塞和非堵塞差别 同步:发出一个功能调用时.在没有得到结果之前,该调用就不返回 异步:当一个异步过程调用发出后.调用者不能立马得到结果.实际处理这个调用的部件在完毕后.通过状态.通知和回调 ...