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. RadioButton的drawableTop图片文字不居中

    在安卓应用的开发中,一般普通应用用到最多的就是底部放一个RadioGroup实现切换的布局,今天在实现的时候,却出现了底部RadiButton的drawableTop图片及文字无法居中的情况,经过对比 ...

  2. python对MySQL进行添加修改删除以及字符串的操作

    # coding=UTF-8 import MySQLdb def dbDperate(sql,param): "定义数据库的添加,修改和删除操作" #获取数据库的连接对象 con ...

  3. sql 知识点

    1 聚集索引和非聚集索引的区别 聚集索引是指 表中存储的数据按照索引的顺序来存储,数据检索效率高,但是对数据更新影响较大:非聚集索引是数据存储在一个地方,索引存储在另一个地方:索引带有指针,指向数据的 ...

  4. Mojom IDL and Bindings Generator

    Mojom IDL and Bindings Generator This document is a subset of the Mojo documentation. Contents Overv ...

  5. CentOS7-1810 系统Samba配置说明

    Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件.SMB(Server Messages Block,信息服务块)通信协议是微软(Microsoft)和英特尔(Intel)在198 ...

  6. POJ-2785 Values whose Sum is 0 Hash表

    题目链接:https://cn.vjudge.net/problem/POJ-2785 题意 给出四组数,每组有n个数 现从每组数中取一个数作为a,b,c,d 问有几组这样的a+b+c+d=0 思路 ...

  7. Unity C# 设计模式(五)建造者模式

    定义: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 组成部分: 1.Builder:给出一个抽象接口,以规范产品对象的各个组成成分的建造.这个接口规定要实现复杂对象的哪 ...

  8. CRC校验原理及步骤

    什么是CRC校验? CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定.循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并 ...

  9. 使用JEECG心得

    使用JEECG心得 我就不做JEECG的介绍了,提供一个网址.能够更加清晰的了解JEECG文档. http://www.jeecg.org/book/jeecg_v3.html 用JEECG已经几乎相 ...

  10. vim 插件之 surround.vim

    surround.vim-这个插件主要是用来插入一些特殊符号的(成对出现) 下载地址 http://www.vim.org/scripts/script.php?script_id=1697 http ...