using System;
using System.Diagnostics;
using System.Text;
namespace VarIntTest
{
class Program
{
public static void Main (string[] args)
{
Console.WriteLine ("Test VarInt encoding");
Console.WriteLine ("{0,6} | = | {1,6} | {2,33}", "Value", "VarInt", "Bits");
Console.WriteLine (new String ('-', 3 * 3 + 6 * 2 + 33 + 1));
for (int n = -12; n < 4; n++) {
uint v = IntToVarInt (n);
Console.WriteLine ("{0,6} | {1} | {2,6} | {3,33}", n, (n == VarIntToInt (v)) ? '=' : '/', v, ShowBits (v));
}
Console.WriteLine ("\n{0,6} | = | {1,6} | {2,33}", "Value", "Base-2", "Bits");
Console.WriteLine (new String ('-', 3 * 3 + 6 * 2 + 33 + 1));
for (int n = -12; n < 4; n++) {
uint v = IntToNeg2 (n);
Console.WriteLine ("{0,6} | {1} | {2,6} | {3,33}", n, (n == Neg2ToInt (v)) ? '=' : '/', v, ShowBits (v));
}
var sw = new Stopwatch ();
for (int n = -100000; n < 100000; n++) {
uint v = IntToVarInt (n);
int i = VarIntToInt (v);
}
sw.Restart ();
for (int n = -100000; n < 100000; n++) {
uint v = IntToVarInt (n);
int i = VarIntToInt (v);
}
sw.Stop ();
Console.WriteLine ("\nInt To VarInt conversion took: {0}", sw.Elapsed);
for (int n = -100000; n < 100000; n++) {
uint v = IntToNeg2 (n);
int i = Neg2ToInt (v);
}
sw.Restart ();
for (int n = -100000; n < 100000; n++) {
uint v = IntToNeg2 (n);
int i = Neg2ToInt (v);
}
sw.Stop ();
Console.WriteLine ("Int To Base-2 conversion took: {0}", sw.Elapsed);
Console.Write ("Press any key to continue . . . ");
Console.ReadKey (true);
}
static StringBuilder sb = new StringBuilder ();
public static string ShowBits (int value)
{
return ShowBits ((uint)value);
}
public static string ShowBits (uint value)
{
sb.Length = 0;
do {
sb.Append ((value & 1) > 0 ? '1' : '0');
unchecked {
value >>= 1;
}
} while (value != 0);
int j = sb.Length - 1, i = 0;
while (i < j) {
var c = sb[i];
sb[i] = sb[j];
sb[j] = c;
i++;
j--;
}
return sb.ToString ();
}
public static uint IntToVarInt (int n)
{
unchecked {
return (uint)((n << 1) ^ (n >> 31));
}
}
public static int VarIntToInt (uint v)
{
unchecked {
var n = (int)v;
return (n >> 1) ^ (-(n & 1));
}
}
public static uint IntToNeg2 (int n)
{
uint val = 0;
uint shift = 1;
while (n != 0) {
int rem;
n = Math.DivRem (n, -2, out rem);
if (rem < 0) {
++n;
}
if (rem != 0) {
val |= shift;
}
shift <<= 1;
}
return val;
}
public static int Neg2ToInt (uint v)
{
int n = 0;
int shift = 0;
int neg = 1;
while (v > 0) {
int rem = (int)(v & 1);
v >>= 1;
n += (rem << shift) * neg;
++shift;
neg *= -1;
}
return n;
}
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uRGlhZ25vc3RpY3M7CnVzaW5nIFN5c3RlbS5UZXh0OwoKbmFtZXNwYWNlIFZhckludFRlc3QKewoJY2xhc3MgUHJvZ3JhbQoJewoJCXB1YmxpYyBzdGF0aWMgdm9pZCBNYWluIChzdHJpbmdbXSBhcmdzKQoJCXsKCQkJQ29uc29sZS5Xcml0ZUxpbmUgKCJUZXN0IFZhckludCBlbmNvZGluZyIpOwoJCgkJCUNvbnNvbGUuV3JpdGVMaW5lICgiezAsNn0gfCA9IHwgezEsNn0gfCB7MiwzM30iLCAiVmFsdWUiLCAiVmFySW50IiwgIkJpdHMiKTsKCQkJQ29uc29sZS5Xcml0ZUxpbmUgKG5ldyBTdHJpbmcgKCctJywgMyAqIDMgKyA2ICogMiArIDMzICsgMSkpOwoJCQlmb3IgKGludCBuID0gLTEyOyBuIDwgNDsgbisrKSB7CgkJCQl1aW50IHYgPSBJbnRUb1ZhckludCAobik7CgkJCQlDb25zb2xlLldyaXRlTGluZSAoInswLDZ9IHwgezF9IHwgezIsNn0gfCB7MywzM30iLCBuLCAobiA9PSBWYXJJbnRUb0ludCAodikpID8gJz0nIDogJy8nLCB2LCBTaG93Qml0cyAodikpOwoJCQl9CgkKCQkJQ29uc29sZS5Xcml0ZUxpbmUgKCJcbnswLDZ9IHwgPSB8IHsxLDZ9IHwgezIsMzN9IiwgIlZhbHVlIiwgIkJhc2UtMiIsICJCaXRzIik7CgkJCUNvbnNvbGUuV3JpdGVMaW5lIChuZXcgU3RyaW5nICgnLScsIDMgKiAzICsgNiAqIDIgKyAzMyArIDEpKTsKCQkJZm9yIChpbnQgbiA9IC0xMjsgbiA8IDQ7IG4rKykgewoJCQkJdWludCB2ID0gSW50VG9OZWcyIChuKTsKCQkJCUNvbnNvbGUuV3JpdGVMaW5lICgiezAsNn0gfCB7MX0gfCB7Miw2fSB8IHszLDMzfSIsIG4sIChuID09IE5lZzJUb0ludCAodikpID8gJz0nIDogJy8nLCB2LCBTaG93Qml0cyAodikpOwoJCQl9CgkKCQkJdmFyIHN3ID0gbmV3IFN0b3B3YXRjaCAoKTsKCQoJCQlmb3IgKGludCBuID0gLTEwMDAwMDsgbiA8IDEwMDAwMDsgbisrKSB7CgkJCQl1aW50IHYgPSBJbnRUb1ZhckludCAobik7CgkJCQlpbnQgaSA9IFZhckludFRvSW50ICh2KTsKCQkJfQoJCQlzdy5SZXN0YXJ0ICgpOwoJCQlmb3IgKGludCBuID0gLTEwMDAwMDsgbiA8IDEwMDAwMDsgbisrKSB7CgkJCQl1aW50IHYgPSBJbnRUb1ZhckludCAobik7CgkJCQlpbnQgaSA9IFZhckludFRvSW50ICh2KTsKCQkJfQoJCQlzdy5TdG9wICgpOwoJCQlDb25zb2xlLldyaXRlTGluZSAoIlxuSW50IFRvIFZhckludCBjb252ZXJzaW9uIHRvb2s6IHswfSIsIHN3LkVsYXBzZWQpOwoJCgkJCWZvciAoaW50IG4gPSAtMTAwMDAwOyBuIDwgMTAwMDAwOyBuKyspIHsKCQkJCXVpbnQgdiA9IEludFRvTmVnMiAobik7CgkJCQlpbnQgaSA9IE5lZzJUb0ludCAodik7CgkJCX0KCQkJc3cuUmVzdGFydCAoKTsKCQkJZm9yIChpbnQgbiA9IC0xMDAwMDA7IG4gPCAxMDAwMDA7IG4rKykgewoJCQkJdWludCB2ID0gSW50VG9OZWcyIChuKTsKCQkJCWludCBpID0gTmVnMlRvSW50ICh2KTsKCQkJfQoJCQlzdy5TdG9wICgpOwoJCQlDb25zb2xlLldyaXRlTGluZSAoIkludCBUbyBCYXNlLTIgY29udmVyc2lvbiB0b29rOiB7MH0iLCBzdy5FbGFwc2VkKTsKCQoJCQlDb25zb2xlLldyaXRlICgiUHJlc3MgYW55IGtleSB0byBjb250aW51ZSAuIC4gLiAiKTsKCQkJQ29uc29sZS5SZWFkS2V5ICh0cnVlKTsKCQl9CgoJCXN0YXRpYyBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIgKCk7CgoJCXB1YmxpYyBzdGF0aWMgc3RyaW5nIFNob3dCaXRzIChpbnQgdmFsdWUpCgkJewoJCQlyZXR1cm4gU2hvd0JpdHMgKCh1aW50KXZhbHVlKTsKCQl9CgoJCXB1YmxpYyBzdGF0aWMgc3RyaW5nIFNob3dCaXRzICh1aW50IHZhbHVlKQoJCXsKCQkJc2IuTGVuZ3RoID0gMDsKCQkJZG8gewoJCQkJc2IuQXBwZW5kICgodmFsdWUgJiAxKSA+IDAgPyAnMScgOiAnMCcpOwoJCQkJdW5jaGVja2VkIHsKCQkJCQl2YWx1ZSA+Pj0gMTsKCQkJCX0KCQkJfSB3aGlsZSAodmFsdWUgIT0gMCk7CgkJCWludCBqID0gc2IuTGVuZ3RoIC0gMSwgaSA9IDA7CgkJCXdoaWxlIChpIDwgaikgewoJCQkJdmFyIGMgPSBzYltpXTsKCQkJCXNiW2ldID0gc2Jbal07CgkJCQlzYltqXSA9IGM7CgkJCQlpKys7CgkJCQlqLS07CgkJCX0KCQkJcmV0dXJuIHNiLlRvU3RyaW5nICgpOwoJCX0KCQkKCQlwdWJsaWMgc3RhdGljIHVpbnQgSW50VG9WYXJJbnQgKGludCBuKQoJCXsKCQkJdW5jaGVja2VkIHsKCQkJCXJldHVybiAodWludCkoKG4gPDwgMSkgXiAobiA+PiAzMSkpOwoJCQl9CgkJfQoJCQoJCXB1YmxpYyBzdGF0aWMgaW50IFZhckludFRvSW50ICh1aW50IHYpCgkJewoJCQl1bmNoZWNrZWQgewoJCQkJdmFyIG4gPSAoaW50KXY7CgkJCQlyZXR1cm4gKG4gPj4gMSkgXiAoLShuICYgMSkpOwoJCQl9CgkJfQoJCQoJCXB1YmxpYyBzdGF0aWMgdWludCBJbnRUb05lZzIgKGludCBuKQoJCXsKCQkJdWludCB2YWwgPSAwOwoJCQl1aW50IHNoaWZ0ID0gMTsKCQkJd2hpbGUgKG4gIT0gMCkgewoJCQkJaW50IHJlbTsKCQkJCW4gPSBNYXRoLkRpdlJlbSAobiwgLTIsIG91dCByZW0pOwoJCQkJaWYgKHJlbSA8IDApIHsKCQkJCQkrK247CgkJCQl9CgkJCQlpZiAocmVtICE9IDApIHsKCQkJCQl2YWwgfD0gc2hpZnQ7CgkJCQl9CgkJCQlzaGlmdCA8PD0gMTsKCQkJfQoJCQlyZXR1cm4gdmFsOwoJCX0KCQkKCQlwdWJsaWMgc3RhdGljIGludCBOZWcyVG9JbnQgKHVpbnQgdikKCQl7CgkJCWludCBuID0gMDsKCQkJaW50IHNoaWZ0ID0gMDsKCQkJaW50IG5lZyA9IDE7CgkJCXdoaWxlICh2ID4gMCkgewoJCQkJaW50IHJlbSA9IChpbnQpKHYgJiAxKTsKCQkJCXYgPj49IDE7CgkJCQluICs9IChyZW0gPDwgc2hpZnQpICogbmVnOwoJCQkJKytzaGlmdDsKCQkJCW5lZyAqPSAtMTsKCQkJfQoJCQlyZXR1cm4gbjsKCQl9Cgl9Cn0=