前文 Base 128 Varints 编码(压缩算法) 介绍了Base 128 Varints这种对数字传输的编码,了解到了这种编码方式是为了最大程度压缩数字的。但是,在前文里,我们只谈论到了正数的情况,那如果出现了负数,该怎么办?zigzag压缩算法解决的就是这个问题。

在聊这个算法之前,我们得先补补课,聊聊二进制补码相关的东东。

一、二进制及补码

我们知道,计算机存储的数据都是二进制的01串,而数字的01串又是以补码的形式存储的,补码是什么东西?为什么要用补码?下面我们一个个来看:

1.原码

要了解补码,首先要了解原码。

什么是原码?简单点说,就是把十进制转为二进制的表示形式,我们用第一个位表示符号(0为非负数,1为负数),剩下的位表示值。比如:

[+8] = [00001000]原

[-8] = [10001000]原

2.反码

我们用第一位表示符号(0为非负数,1为负数),剩下的位,非负数保持不变,负数按位求反。比如:

[+8] = [00001000]原 = [0000 1000]反

[-8] = [10001000]原 = [1111 0111]反

就是说:正数的反码是本身,负数的反码保持符号位不变,其他位逐位取反

3.补码

首先,我们来看为什么会出现补码,我们先来看2个问题

第一,0居然用2个编码(+0和-0)来表示了:

原码:[0000 0000]原 = [1000 0000]原

反码:[0000 0000]反 = [1111 1111]反

第二,我们来看一个现象

1 + (-1)

= [00000001]原 + [1000 0001]原

= [10000010]原

= -2

明显是不对的!

反码:

1 + (-1)

= [00000001]反 + [1111 1110]反

= [1111 1111]反

= -0

表现的好诡异!(正常应该是 0000 0000)

为了解决这些问题,我们在计算机体系中引入了补码。

现在我们来看补码怎么取:

我们用第一位表示符号(0为非负数,1为负数),剩下的位非负数保持不变,负数按位求反末位加一。

[+8] = [00001000]原 = [0000 1000]补

[-8] = [10001000]原 = [1111 0111]反 = [1111 1000]补

即:正数的补码是自己本身,负数的补码口诀为:逐位取反,末位加1

引进了补码之后,我们看看计算的情况:

1 + (-1)

= [00000001]补 + [1111 1111]补

= [0000 0000]补

= 0

很明显,通过这样的方式,计算机进行运算的时候,就不用关心符号这个问题,而只需要按照统一的逢二进一的原则进行运算就可以了。

好了,补充了这些知识之后,可以进入正题了。

二、zigzag压缩算法

前文说到了,在绝大多数情况下,我们使用到的整数,往往是比较小的。然而,我们为了正确,又不得不把很多无用的0进行传输。Base 128 Varints编码很好地解决了上面说的问题,但是,如果传输的数字出现了负数,会出现什么情况呢?

依然举个很简单的例子,假设我要传输数字-1,会怎样传输呢?

[-1]=[10000000 00000000 00000000 00000001]原 = [11111111 11111111 11111111 11111110]反 = [11111111 11111111 11111111 11111111]补

前面的废物0,到这里居然变成了废物1了,怎么样才能进行压缩呢?

zigzag给出了一个很巧的方法:我们之前讲补码讲过,补码的第一位是符号位,他阻碍了我们对于前导0的压缩,那么,我们就把这个符号位放到补码的最后,其他位整体前移一位

-1= [11111111_11111111_11111111_11111111]补= [11111111_11111111_11111111_11111111]符号后移

但是即使这样,也是很难压缩的,因为数字绝对值越小,他所含的前导1越多。于是,这个算法就把负数的所有数据位按位求反,符号位保持不变,得到了这样的整数:

-1= [11111111_11111111_11111111_11111111]补= [11111111_11111111_11111111_11111111]符号后移=[00000000_00000000_00000000_00000001]符号后移

我们熟悉的前面的一堆0又出现了,又可以愉快地使用Base 128 Varints算法进行编码了。

那么,如果是正数的情况,这个算法改怎么处理呢?如果数字是正数,符号位一样放到最后,其他数据全部保持不变就行了,例如:

[1]

= (00000000_00000000_00000000_00000001)补

= (00000000_00000000_00000000_00000010)符号后移

= (00000000_00000000_00000000_00000010)zigzag

这样一弄,正数、0、负数都有同样的表示方法了,我们就可以对小整数进行压缩了

zigzag压缩算法的更多相关文章

  1. RPC-Thrift(三)

    TProtocol TProtocol定义了消息怎么进行序列化和反序列化的. TProtocol的类结构图如下: TBinaryProtocol:二进制编码格式: TCompactProtocol:高 ...

  2. JPEG图像压缩算法流程详解

    JPEG图像压缩算法流程详解 JPEG代表Joint Photographic Experts Group(联合图像专家小组).此团队创立于1986年,1992年发布了JPEG的标准而在1994年获得 ...

  3. ZigZag编码

    ZigZag编码 在网络传输和数据存储场景中,需要对数据进行压缩.数据压缩的算法非常多,但大部分的数据压缩算法的原理是通过某种编码方式不存储数据中的0比特位,因此0比特位越多,数据压缩的效果越好.Zi ...

  4. ZIP压缩算法详细分析及解压实例解释

    最近自己实现了一个ZIP压缩数据的解压程序,觉得有必要把ZIP压缩格式进行一下详细总结,数据压缩是一门通信原理和计算机科学都会涉及到的学科,在通信原理中,一般称为信源编码,在计算机科学里,一般称为数据 ...

  5. LZ77压缩算法编码原理详解(结合图片和简单代码)

    前言 LZ77算法是无损压缩算法,由以色列人Abraham Lempel发表于1977年.LZ77是典型的基于字典的压缩算法,现在很多压缩技术都是基于LZ77.鉴于其在数据压缩领域的地位,本文将结合图 ...

  6. [LeetCode] Zigzag Iterator 之字形迭代器

    Given two 1d vectors, implement an iterator to return their elements alternately. For example, given ...

  7. [LeetCode] Binary Tree Zigzag Level Order Traversal 二叉树的之字形层序遍历

    Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to ...

  8. [LeetCode] ZigZag Converesion 之字型转换字符串

    The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...

  9. 【leetcode】ZigZag Conversion

    题目简述 The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows ...

随机推荐

  1. ucore操作系统学习(六) ucore lab6线程调度器

    1. ucore lab6介绍 ucore在lab5中实现了较为完整的进程/线程机制,能够创建和管理位于内核态或用户态的多个线程,让不同的线程通过上下文切换并发的执行,最大化利用CPU硬件资源.uco ...

  2. java.lang.UnsupportedOperationException: Unable to create instance of org.fisco.bcos.web3j.abi.datatypes.generated.Int256

    Contract Address : 0x967f92adc229b77dda64b42af21ea1ff1b0702eb Unable to create instance of org.fisco ...

  3. nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)

    Mac上启动nginx报如上错误,原因是80端口已被占用,可能有些服务未能成功关闭. 解决:键入命令 sudo nginx -s stop ( 或 sudo nginx -s  quit) ,然后 s ...

  4. 最新快手抖音短视频源码web+APP架设教程+完整数据

    最新更新快手抖音短视频源码web+APP架设教程+完整数据完美运行 视频直播源码,好东西,反正有人要就是了. 下载地址:https://pan.baidu.com/wap/init?surl=POU5 ...

  5. Hadoop框架:Yarn基本结构和运行原理

    本文源码:GitHub·点这里 || GitEE·点这里 一.Yarn基本结构 Hadoop三大核心组件:分布式文件系统HDFS.分布式计算框架MapReduce,分布式集群资源调度框架Yarn.Ya ...

  6. MISC-吹着贝斯扫二维码

    题目 [安洵杯 2019]吹着贝斯扫二维码 解压附件,有36个文件和一个压缩包,压缩包带密码和备注 分析 文件类型 随便打开一个不明文件,是jpg图片啊(FF D8 FF) 改一个试试,有一个小块二维 ...

  7. 三方登录微博url接口

    1.创建apps/oauth模块进行oauth认证 '''2.1 在apps文件夹下新建应用: oauth''' cd syl/apps python ../manage.py startapp oa ...

  8. JavaSE04-Switch&循环语句

    1.Switch 格式: 1 switch (表达式) { 2 case 1: 3 语句体1; 4 break; 5 case 2: 6 语句体2; 7 break; 8 ... 9 default: ...

  9. [GXYCTF2019]simple CPP

    [GXYCTF2019]simple CPP 一.查壳 无壳,64位程序 二.IDA分析 找到主函数后动态调试,看的更清楚 经过调试后我们可以找到len就是储存字符串长度的变量,之后判断长度是不是大于 ...

  10. Application Data in Docker 笔记

    Application Data in Docker By default all files created inside a container are stored on a writable ...