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. POJ 1274 二分图匹配

    匈牙利算法 裸题 //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> ...

  2. 归档备份被删,GoldenGate无法抽取数据

    发生错误如下,源端EXTRACT进程异常中止,查看日志,发现如下错误. 2014-07-23 01:32:13  ERROR   OGG-00446  Oracle GoldenGate Captur ...

  3. 有用的 Bash 快捷键清单

    作者: Sk 译者: LCTT Sun Yongfei 现如今,我在终端上花的时间更多,尝试在命令行完成比在图形界面更多的工作.随着时间推移,我学了许多 BASH 的技巧.这是一份每个 Linux 用 ...

  4. 解决mongodb TypeError: Cannot read property 'XXX' of null 问题

    有时候我们的字段里的数据为空而去查询就会报错. 比如以下形式: “cartList”:[] “cartList”:[{}] “cartList”:{} “cartList”:null 在查询的时候加上 ...

  5. bzoj1293 [SCOI2009] 生日礼物 队列

    题目描述 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有N个,分为K种.简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置).某些坐标上可以没有彩珠,但多个彩珠也可以出现在 ...

  6. CF402E Strictly Positive Matrix(矩阵,强联通分量)

    题意 给定一个 n∗n 的矩阵 A,每个元素都非负判断是否存在一个整数 k 使得 A^k 的所有元素 >0 n≤2000(矩阵中[i][i]保证为1) 题解 考虑矩阵$A*A$的意义 ,设得到的 ...

  7. lsof---查看你进程开打的文件

    lsof命令用于查看你进程开打的文件,打开文件的进程,进程打开的端口(TCP.UDP).找回/恢复删除的文件.是十分方便的系统监视工具,因为lsof命令需要访问核心内存和各种文件,所以需要root用户 ...

  8. Markdown编辑器 常用语法

    一.标题 示例: # 1这是一级标题 ## 2这是二级标题 ### 3这是三级标题 #### 4这是四级标题 ##### 5这是五级标题 ###### 6这是六级标题 效果如下: 1这是一级标题 2这 ...

  9. 09-breack语句

  10. Java基础学习总结(26)——JNDI入门简介

    JNDI是 Java 命名与目录接口(Java Naming and Directory Interface),在J2EE规范中是重要的规范之一,不少专家认为,没有透彻理解JNDI的意义和作用,就没有 ...