二进制的编码

  通常计算机系统中讨论二进制的编码问题涉及到的有:原码、反码、补码,这里简单探讨一下他们之间的关系。

原码与反码

  原码是最先被提出的一种编码方式,使用最高位表示符号(0表示正,1表示负),其余位表示数值。原码存在一个问题,就是自然界中 +0 和 -0 是相同的,但 +0 的原码是 0b00,而 -0 的原码是 0b10,这样 0 出现两种编码方式。

  反码是从原码到补码的过渡阶段,对于任意一个整数 n ,它的反码:

  • n > 0:n的反码和原码相同
  • n < 0:n的反码等于原码进行如下变换:1.符号位不变,2.其余位按位取反;

反码同样没有解决 0 编码格式不唯一的问题,但它只是一个中间过渡;

模数与补数

  补码是系统使用的编码形式,在介绍补码前,需要了解一下模数和补数的概念。

  通常称:

  x % y = z

  为 x 模 y,其中 % 是取模运算符,y 称为模数,z 称为 x 在模 y 下的补数。

  我们来看下面的时钟,当前指向 8 点,如果只考虑小时的话,那么时钟的模数就是12,对于当前指向 8 点的时针,假如我们希望它走到 6 点,则至少有两种方法:

  1. 8 + (- 2) = 6

  2. (8 + 10) % 12 = 6

也就是说,如果定义顺时针为正,逆时针为负的话,我们可以顺时针转动时针10个小时,也可以逆时针移动时针2个小时,时针最终都会停留在6点上。

  此时对于 -2 而言,它的补数就是 10,10 = 12 - |-2|,也就是说 一个负数的补数 等于 模数 减去 负数 的绝对值。之所以引入补数,是希望在一个类似钟面这样刻度有限、会出现循环往复的系统中,将减法和加法统一起来,使得减法运算可以一致的使用加法运算来处理。

补码

  在计算机系统内,补码和补数的概念是一致的,那模数是什么?以一个32位长度的整数而言,模数就是 2^32。就好比把一个圆盘分成了2^32份,在这个系统中,最小值是 0 ,最大值是2^32-1,当2^32-1再向前走1位时,又回到了0。这种使用定长内存表示数值的方式使得补码成为合适的编码方式。

  

  回到之前的介绍上来,对于任意一个整数 n ,它的补码:

  • n 为正数,补码就是其原码;
  • n 为负数,补码 = (n的反码 + 1) = (n的原码的符号位不变(为1),其余位取反) + 1 = (n的绝对值的原码按位取反) + 1
  • n 为 0,补码唯一确定为 0 ;

  对于一个负数,它的反码是自己绝对值的原码按位取反后加1,为什么?

  前面已经介绍过,负数的补数等于模数减去其绝对值,即 32 位负整数 n 的反码就是 2^32 - |n|,等于 (2^32-1) - |n| + 1。而 2^32-1 使用二进制表示刚好为32位1,它减去 |n|,其实就是对 n 的绝对值按位取反了!

  此外,对于 -0 的二进制原码 0b100...00,其补码为 0b1111...11 + 1 等于0,而 +0 的补码还是0,从而避免了正负0的编码结果不同的问题。

  总结起来,正数和0的补码就是其原码,而知道了原码、反码、补码之间的关系和补数是怎么求的,就不难求得负数的补码了。补码之间一致地使用加法运算,即加上一个负数(减法),等于加上这个负数的补码。而拿到一个负数的补码,再对这个补码进行一遍求补的运算,就可以得到原数的原码了!

  还是由于补码成立的基础,即使用定长的位数表示一个整数,也不难理解为什么补码的运算不可避免的会存在溢出——负 + 负变正 或 正+正变负 的情况了。

时间: 2024-12-24 06:45:26

二进制的编码的相关文章

使用base64对图片的二进制进行编码,使其可以利用ajax进行显示

有时候我们需要动态的将图片的二进制在页面上进行显示,如我们需要弄一个验证码的功能,那么如果我们的验证码的图片在后台得到的是该图片的二进制,那么当我们需要在页面上点击一个按钮利用ajax进行切换的时候,如果在后台直接返回的是该图片的二进制,那么该图片是无法进行显示的. 直接返回字节流给img标签的src是可以的,如<img src="servlet/CheckCode">,但在之后进行切换的时候 使用ajax请求,如果仅仅返回图片的二进制然后把它传给img的src是不能的,目

Python基础 二进制和字符编码

二进制定义 二进制是计算技术中广泛采用的一种数制.二进制数据是用0和1两个数码来表示的数.它的基数为2,进位规则是"逢二进一",借位规则是"借一当二",由18世纪德国数理哲学大师莱布尼兹发现.当前的计算机系统使用的基本上是二进制系统,数据在计算机中主要是以补码的形式存储的.计算机中的二进制则是一个非常微小的开关,用"开"来表示1,"关"来表示0. 二进制与十进制转换 我们已经发现,二进制的第n位代表的十进制值都刚好遵循着2的n

java对文件的二进制流base64编码解码

1.java对文件的二进制流base64编码解码 一般保存文件的时候选择的方式是将url存进数据库.今天遇到一个对接传文件流的二进制base64编码,简单记录一下. 依赖于commons-io包和commons-codec包. 编码的方法如下: public static String encodeFile(File file) throws IOException { byte[] readFileToByteArray = FileUtils.readFileToByteArray(file

base64编码

Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation. Base64是一种用64个可打印字符来表示任意二进制数据的方法,不能用于加密. 为什么使用Base64格式编码? 在只支持纯文本的协议中需要保存非字符类数据(url(dat

机智零崎不会没梗Ⅱ (哈夫曼编码、优先队列)

题目描述 你满心欢喜的召唤出了外星生物,以为可以变身超人拥有强大力量战胜一切怪兽,然而面对着身前高大的外星生物你一脸茫然,因为,你懂M78星云语吗?不过不用担心,因为零崎非常机智,他给出了关键性的提示:“讲道理,日语可是全宇宙通用语,所以为什么不试试和外星人讲日语呢?” 不过现在外星生物说的话都是“[email protected]#$%^&%#%I&!……”这样的东西,你要怎么转换成日语呢? 作位全宇宙通用的日语,自然有一套万能的转换算法,那就是Huffman编码转换!当然了这肯定不是普

URL编码

原链接在这里 Base64编码 所谓Base64,就是说选出64个字符----小写字母a-z.大写字母A-Z.数字0-9.符号"+"."/"(再加上作为垫字的"=",实际上是65个字符)----作为一个基本字符集.然后,其他所有符号都转换成这个字符集中的字符. 第一步,将每三个字节作为一组,一共是24个二进制位. 第二步,将这24个二进制位分为四组,每个组有6个二进制位. 第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节. 第四步,

【转】证书和编码

证书与编码 本至上,X.509证书是一个数字文档,这个文档根据RFC 5280来编码并/或签发. 实际上,“X.509证书”经常被用来指代IETF的PKIX(Public Key Infrastructure)证书和X.509 v3 证书标准中的CRL(Certificate Revocation List). X509 文件扩展名 首先我们要理解文件的扩展名代表什么.DER.PEM.CRT和CER这些扩展名经常令人困惑.很多人错误地认为这些扩展名可以互相代替.尽管的确有时候有些扩展名是可以互换

字符编码【转载】

转载:http://www.techug.com/character-encoding 字符集和字符编码 编程技术2015-3-26TECHUG2条评论 本文将简述字符集,字符编码的概念.以及在遭遇乱码时的一些常用诊断技巧. 背景:字符集和编码无疑是IT菜鸟甚至是各种大神的头痛问题.当遇到纷繁复杂的字符集,各种火星文和乱码时,问题的定位往往变得非常困难.本文就将会从原理方面对字符集和编码做个简单的科普介绍,同时也会介绍一些通用的乱码故障定位的方法以方便读者以后能够更从容的定位相关问题.在正式介绍

python中的编码与解码

编码与解码 首先,明确一点,计算机中存储的信息都是二进制的 编码/解码本质上是一种映射(对应关系),比如‘a’用ascii编码则是65,计算机中存储的就是00110101,但是显示的时候不能显示00110101,还是要显示'a',但计算机怎么知道00110101是'a'呢,这就需要解码,当选择用ascii解码时,当计算机读到00110101时就到对应的ascii表里一查发现是'a',就显示为'a' 编码:真实字符与二进制串的对应关系,真实字符→二进制串 解码:二进制串与真实字符的对应关系,二进制