Last active
April 24, 2017 03:11
-
-
Save leolovenet/4dfb562a6d964106f99854b67fa07ed1 to your computer and use it in GitHub Desktop.
一个压缩小整数的算法zipzag,原文来自这里, http://mp.weixin.qq.com/s?__biz=MzA3MDExNzcyNA==&mid=2650392086&idx=1&sn=6a2ecfe2548f121a4726d03bf23f4478
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//一个压缩小整数的算法,原文来自这里 | |
//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