Reputation: 5018
I have a 4 length slice stored an int value like this:
[159 124 0 0]
Then I tried val, encodeBytes := binary.Uvarint(slice)
, but got wrong val
:
val = 15903, encodebytes = 2
The correct val
should be 31903
, what's wrong with it?
Here is the code:
http://play.golang.org/p/kvhu4fNOag
Upvotes: 2
Views: 846
Reputation: 21081
According to the binary package documentation the encoding used to interpret the byte sequence is the one available here. It specifies that bytes are interpreted as:
Each byte in a varint, except the last byte, has the most significant bit (msb) set – this indicates that there are further bytes to come. The lower 7 bits of each byte are used to store the two's complement representation of the number in groups of 7 bits, least significant group first.
The binary representation of [159 124 0 0]
is:
1001 1111 , 0111 1100 , 0000 0000, 0000 0000
The most significant bit (MSB) of the first byte is set so the second byte will also be interpreted. The second bytes MSB is not set so the remaining bytes are ignored.
By dropping the MSB of the bytes interpreted the bits we get:
001 1111 , 111 1100
These two groups are then reversed before being interpreted as the number:
111 1100 , 001 1111
concatenated:
0011 1110 0001 1111
Converting this back to decimal we get:
1 + 2 +4 + 8 + 16 + 0 + 0 + 0 + 0 + 512 + 1024 + 2048 + 4096 + 8192 = 15903
As James' and peterSO's post indicates you probably want to use binary.LittleEndian.Uint32
instead.
Upvotes: 1
Reputation: 43909
From the expected result, it sounds like you're trying to decode a little endian 32-bit integer. The binary.Uvarint
function is the wrong one for the job though, since it decodes the variable length integer encoding used by the Protocol Buffers specification.
Instead, try using binary.LittleEndian.Uint32()
:
val := binary.LittleEndian.Uint32(slice)
Upvotes: 1
Reputation: 166626
For example,
package main
import (
"encoding/binary"
"fmt"
)
func main() {
bytes := []byte{159, 124, 0, 0}
integer := int(binary.LittleEndian.Uint32(bytes))
fmt.Println(bytes, integer)
}
Output:
[159 124 0 0] 31903
Upvotes: 1