Skip to content

Instantly share code, notes, and snippets.

@leolovenet
Last active April 24, 2017 03:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leolovenet/4dfb562a6d964106f99854b67fa07ed1 to your computer and use it in GitHub Desktop.
Save leolovenet/4dfb562a6d964106f99854b67fa07ed1 to your computer and use it in GitHub Desktop.
//一个压缩小整数的算法,原文来自这里
//http://mp.weixin.qq.com/s?__biz=MzA3MDExNzcyNA==&mid=2650392086&idx=1&sn=6a2ecfe2548f121a4726d03bf23f4478
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
typedef unsigned char byte;
////http://stackoverflow.com/questions/111928/is-there-a-printf-converter-to-print-in-binary-format?page=1&tab=active#tab-top
//assumes little endian
void printBits(size_t const size, void const *const ptr) {
unsigned char *b = (unsigned char *) ptr;
unsigned char byte;
int i, j;
for (i = size - 1; i >= 0; i--) {
for (j = 7; j >= 0; j--) {
byte = (b[i] >> j) & 1;
printf("%u", byte);
}
if (i > 0) printf("_");
}
puts("");
}
int int_to_zipzag(int n) {
return (n << 1) ^ (n >> 31);
}
int zipzag_to_int(int n) {
return ((unsigned int) n >> 1) ^ -(n & 1);
}
int write_to_buffer(int zz, byte *buf, int size) {
int ret = 0;
for (int i = 0; i < size; i++) {
if ((zz & (~0x7F)) == 0) {
buf[i] = (byte) zz;
ret = i + 1;
break;
} else {
buf[i] = (byte) ((zz & 0x7F) | 0x80);
zz = (unsigned int) zz >> 7;
}
}
return ret;
}
//我实现方式
int read_from_buffer2(byte *buf, int max_size) {
int result = 0; //最后要返回的int型值
int offset = 0; //ret需要偏移的位数(即目前是处理第几个 7bit 位)
for (int i = 0; i < max_size; i++, offset += 7) {
result |= (buf[i] & 0x7F) << offset;
if ((buf[i] & 0x80) == 0) break;
}
return result;
}
int read_from_buffer(byte *buf, int max_size) {
int ret = 0;
int offset = 0;
for (int i = 0; i < max_size; i++, offset += 7) {
byte n = buf[i]; //取出一组 7bit 位, 第 8bit 位为符号位,代表是否为最后一组 7bit 位
if ((n & 0x80) != 0x80) { //第 8bit 位为 0 (表示为最后一组 7bit 位)
ret |= (n << offset);
break;
} else {
ret |= ((n & 0x7f) << offset);
}
}
return ret;
}
int main() {
int a[] = {
(int) (-pow(2L, 32)),
-1000,
-10000,
-1,
0,
1,
1000,
10000,
getpid(),
rand()-10000,
(int) (pow(2L, 31) - 1L)
};
for (int i = 0; i < sizeof(a) / sizeof(int); i++) {
int n = a[i];
printf("number: %15d ", n);
printBits(sizeof(n), &n);
int zz = int_to_zipzag(n);
printf("zipnum: %15d ", zz);
printBits(sizeof(zz), &zz);
byte write_buffer[5] = {0};
int write_size = write_to_buffer(zz, write_buffer, sizeof(write_buffer));
printf("zipbuf: %11dbyte ", write_size);
printBits(write_size, &write_buffer);
int read_num = read_from_buffer(write_buffer, write_size);
printf("re1num: %15d ", read_num);
printBits(sizeof(read_num), &read_num);
int read_num2 = read_from_buffer2(write_buffer, sizeof(write_buffer));
printf("re2num: %15d ", read_num2);
printBits(sizeof(read_num2), &read_num2);
int org1_num = zipzag_to_int(read_num);
printf("numbe1: %15d ", org1_num);
printBits(sizeof(org1_num), &org1_num);
int org2_num = zipzag_to_int(read_num2);
printf("numbe2: %15d ", org2_num);
printBits(sizeof(org2_num), &org2_num);
puts("");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment