~obeancomputer/bitter

a1dd57402151e289a6297b42f5a3bafe4769730f — ocsmit 1 year, 1 month ago fa43358
Add encoding routines
3 files changed, 91 insertions(+), 0 deletions(-)

A src/encoding.c
A src/encoding.h
M tests/tests.c
A src/encoding.c => src/encoding.c +60 -0
@@ 0,0 1,60 @@
/**
 * @file
 * @brief Routines for encoding and decoding integers
 */

#include "encoding.h"

#include <stdint.h>
#include <stdio.h>


uint32_t count_trailing_zeros(unsigned int v)
{
    // modified from:
    // http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup
    static const uint32_t Mod37BitPosition[] = {
      32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4,
      7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5,
      20, 8, 19, 18
    };

    // map a bit value mod 37 to its position
    return Mod37BitPosition[(-v & v) % 37];
}


unsigned int unary_encode(uint32_t k)
{
    // code 1 . 0 k times (e.g. 3 := 1 . 000
    return (1 << k);

}

unsigned int gamma_encode(uint32_t k)
{
    uint32_t length, offset;

    // floor(log_2(k))
    length = (uint32_t) log2(k);
    offset = k - (1 << length);

    // Unary coded offset . length 
    // e.g. 13 (l = 3, o = 5) := 101.1000
    return (offset << (length+1) | ((1 << length)));
}

unsigned int gamma_decode(unsigned int k)
{
    uint32_t l = 0;
    uint32_t o = 0;

    l = count_trailing_zeros(k);
    k >>= l;

    // Mask for l bits
    o = (1 << l) - 1 & (k >> 1);
    return (1 << l) + o;
}



A src/encoding.h => src/encoding.h +19 -0
@@ 0,0 1,19 @@
#ifndef ENCODING_H_
#define ENCODING_H_

#include <stdint.h>
#include <math.h>




uint32_t count_trailing_zeros(unsigned int v);

unsigned int unary_encode(uint32_t k);

unsigned int gamma_encode(uint32_t k);

unsigned int gamma_decode(unsigned int k);

#endif // !ENCODING_H_


M tests/tests.c => tests/tests.c +12 -0
@@ 1,9 1,12 @@
#include "tests.h"
#include "assert.h"
#include <stdint.h>
#include <stdio.h>
#include "../src/bitarr.h"
#include "../src/bitops.h"
#include "../src/bitarr_io.h"
#include "../src/encoding.h"






@@ 132,6 135,15 @@ TEST("Read from disk")

BitArray_free(bit_arr);

TEST("Gamma encoding")
{
    uint32_t og_int = 13;
    unsigned int gc = gamma_encode(og_int);
    gc = gamma_decode(gc);
    assert(og_int == gc);
    printf("✔ Gamma coding\n");
}