2017-09-05 2 views
0

정수 압축과 관련된 작업을하고 있습니다.
가변 바이트 인코딩 알고리즘을 C++로 구현했습니다 (아래 스 니펫 참조). 골란에서 가변 바이트 인코딩 알고리즘을 구현하는 방법

나는 memcpy()이처럼 내가 메모리에 int 유형 사이에 string 또는 tune 형식을 변환 할 수 있기 때문에 golang에서이를 구현하는 방법에 대해 궁금합니다.

그런 다음 encoding/binary은 uint8을 1 바이트로 인코딩 할 수 있고, unint16을 2 바이트로 인코딩 할 수 있고, 4 가지 유형으로 uint32를 인코딩 할 수있는 binary.Write() 패키지를 알아 냈습니다.

하지만 3 바이트 만 사용하여 2097152에서 268435456 사이의 정수를 인코딩하는 방법은 무엇입니까?

스 니펫과 비슷한 변환 방법이 있습니까?

void encode(int value, char* code_list, int& len) { 

    int bit_value = 0; 
    int bit_num = 0; 

    if (value < 128) { 
    bit_num = 1; 
    } else if (value < 16384) { 
    bit_num = 2; 
    bit_value = 1; 
    } else if (value < 2097152) { 
    bit_num = 3; 
    bit_value = 3; 
    } else { 
    bit_num = 4; 
    bit_value = 7; 
    } 
    value <<= bit_num; 
    value += bit_value; 
    memcpy(code_list + len, (char*) &value, bit_num); 
    len += bit_num; 

} 

답변

3

인코딩은 첫 번째 바이트에서 1 최하위 비트의 개수가 인코딩 된 값이 얼마나 많은 바이트를 알 수 있도록합니다.

endianness (C 버전의 경우)에 의존하지 않고 memcpy이 아닌 io.Writer을 사용하는 코드의 Go 구현은 다음과 같습니다.

package main 

import (
    "fmt" 
    "bytes" 
    "io" 
) 

func encode(w io.Writer, n uint64) error { 
    bytes := 0 
    switch { 
    case n < 128: 
     bytes = 1 
     n = (n << 1) 
    case n < 16834: 
     bytes = 2 
     n = (n << 2) | 1 
    case n < 2097152: 
     bytes = 3 
     n = (n << 3) | 3 
    default: 
     bytes = 4 
     n = (n << 4) | 7 
    } 
    d := [4]byte{ 
     byte(n), byte(n>>8), byte(n>>16), byte(n>>24), 
    } 
    _, err := w.Write(d[:bytes]) 
    return err 
} 

func main() { 
    xs := []uint64{0, 32, 20003, 60006, 300009} 
    var b bytes.Buffer 
    for _, x := range xs { 
     if err := encode(&b, x); err != nil { 
      panic(err) 
     } 
    } 
    fmt.Println(b.Bytes()) 
} 
+0

https://play.golang.org/p/jr0NypSnlW이있어, 감사 :

은 그것을 실행을 참조하십시오. – Will

관련 문제