How do you write an integer to LEB128 format in Go? I'm trying to encode an int32 to a Minecraft VarInt, so far I've tried importing the example on the wiki to Go. I get the wrong results when testing though, wiki says -1 should equal [255 255 255 255 15], but I get [255 255 255 255 255] instead. What I'm I doing wrong here?
func WriteVarInt2(v int32) []byte{
var out []byte
c := 0
for{
currentByte := byte(v & 0b01111111)
v >>= 7
if v != 0 {
currentByte |= 0b10000000
}
out = append(out, currentByte)
c++
if c >= 5 || v == 0{
return out
}
}
}
The problem is with the shifting operation.
>>
is arithmetic shift right, >>>
is logical shift right. The difference is that >>
brings in the sign bit (on the left), while >>>
brings in zeros (whatever the sign bit was).
The algorithm of LEB128's Varint uses logical shift, and Go's >>
is arithmetic shift.
There is no distinct logical shift in Go, but if you treat the number as unsigned, you'll get exactly that:
func WriteVarInt2(v_ int32) []byte {
v := uint32(v_)
// rest of your function unchanged
// ...
}
Testing it:
fmt.Println(WriteVarInt2(-1))
Output is as expected (try it on the Go Playground):
[255 255 255 255 15]