5

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
       }
    }
}
icza
  • 389,944
  • 63
  • 907
  • 827
Angel
  • 81
  • 1
  • 6

1 Answers1

6

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]
icza
  • 389,944
  • 63
  • 907
  • 827