zigzag压缩算法
前文 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压缩算法的更多相关文章
- RPC-Thrift(三)
TProtocol TProtocol定义了消息怎么进行序列化和反序列化的. TProtocol的类结构图如下: TBinaryProtocol:二进制编码格式: TCompactProtocol:高 ...
- JPEG图像压缩算法流程详解
JPEG图像压缩算法流程详解 JPEG代表Joint Photographic Experts Group(联合图像专家小组).此团队创立于1986年,1992年发布了JPEG的标准而在1994年获得 ...
- ZigZag编码
ZigZag编码 在网络传输和数据存储场景中,需要对数据进行压缩.数据压缩的算法非常多,但大部分的数据压缩算法的原理是通过某种编码方式不存储数据中的0比特位,因此0比特位越多,数据压缩的效果越好.Zi ...
- ZIP压缩算法详细分析及解压实例解释
最近自己实现了一个ZIP压缩数据的解压程序,觉得有必要把ZIP压缩格式进行一下详细总结,数据压缩是一门通信原理和计算机科学都会涉及到的学科,在通信原理中,一般称为信源编码,在计算机科学里,一般称为数据 ...
- LZ77压缩算法编码原理详解(结合图片和简单代码)
前言 LZ77算法是无损压缩算法,由以色列人Abraham Lempel发表于1977年.LZ77是典型的基于字典的压缩算法,现在很多压缩技术都是基于LZ77.鉴于其在数据压缩领域的地位,本文将结合图 ...
- [LeetCode] Zigzag Iterator 之字形迭代器
Given two 1d vectors, implement an iterator to return their elements alternately. For example, given ...
- [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 ...
- [LeetCode] ZigZag Converesion 之字型转换字符串
The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...
- 【leetcode】ZigZag Conversion
题目简述 The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows ...
随机推荐
- 掌握 Promise 的逻辑方法
Promise 是 ES2015 新增的对象 Promise 对象有几个组合方法,可以将多个承诺合并成一个进行处理 分别是 Promise.all, Promise.race, Promise.all ...
- moviepy音视频开发:音频合成类CompositeAudioClip介绍
☞ ░ 前往老猿Python博文目录 ░ CompositeAudioClip是AudioClip的直接子类,用于将几个音频剪辑合成为一个音频剪辑.CompositeAudioClip类只有一个构造方 ...
- 第8.16节 Python重写自定义类的__str__方法
一. 引言 上节结合案例介绍了重写__repr__方法的关注点,重写__repr__方法的要点是要准确的输出开发人员关注的信息,并便于开发人员使用相关信息.而__str__方法是为最终用户返回类的相关 ...
- PyQt(Python+Qt)学习随笔:QTreeWidget树型部件中的QTreeWidgetItem项构造方法
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTreeWidget树型部件的项是单独的类对象,这个类就是QTreeWidgetItem. QTr ...
- PyQt(Python+Qt)学习随笔:使用pyqtConfigure建立信号和槽的连接
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在PyQt中,一般信号和槽的连接是通过connect方法建立的,语法如下: connect(slot ...
- ABP框架使用Mysql数据库,以及基于SQLServer创建Mysql数据库的架构和数据
ABP默认的数据库是SQLServer,不过ABP框架底层是EF框架,因此也是很容易支持其他类型的数据库的,本篇随笔介绍在ABP框架使用Mysql数据库,以及基于SQLServer创建MySql数据库 ...
- Scrum冲刺_Day01
一.团队展示: 1.项目:light_note备忘录 2.队名:删库跑路队 3.团队成员 队员(不分先后) 项目角色 黄敦鸿 后端工程师.测试 黄华 后端工程师.测试 黄骏鹏 后端工程师.测试 黄源钦 ...
- 团队作业 需求改进&系统设计
PaChat聊天系统 一.需求&原型改进: 1.针对课堂讨论环节老师和其他组的问题及建议,对修改选题及需求进行修改 问题1:功能划分条理不够清晰. 修改1:改为流程图的形式. 问题2:功能不能 ...
- Zabbix 新版微信告警-转载
Zabbix 新版微信告警 Zabbix可以通过多种方式把告警信息发送到指定人,常用的有邮件,短信报警方式,但是越来越多的企业开始使用zabbix结合微信作为主要的告警方式,这样可以及时有效的把告警信 ...
- jmeter__编写脚本学习笔记、备忘
web持续添加 前言: 1. token就是令牌,比如你授权(登录)一个程序时,他就是个依据,判断你是否已经授权该软件:也叫关联 2. cookie就是写在客户端的一个txt文件,里面包括你登录信息之 ...