16

I see some answers to exactly the same question I have: How to convert Byte array to int in GO programming language?

I wrote below function to convert byte array to int

func convertByteToInt(in []byte) int32 {
    return  (int32(in[0]) << 24 | int32(in[1]) << 16 | int32(in[2]) << 8 | int32(in[3]))
}

Before that, I made sure that byte array has correct(base 256) values. in[0] = 54 (ASCII for 6), in[1] = 54 (ASCII for 6), in[2] = 49 (ASCII for 1), in[3] = 49 (ASCII for 1).

So I am expecting to retrieve integer 6611 value from byte array, but I ended up getting 909521201. I fail to understand what is exactly going on in such a simple conversion. Can anyone flash some light?

THanks

1
  • 1
    You've got a integer formatted as a decimal number string in a []byte. Convert your []byte to string and use strconv.Atoi and friends. Bitfiddling is plain nonsense here. (Not worth an answer.) Commented Dec 4, 2014 at 6:55

4 Answers 4

15

@Volker is right in his comment, you don't have a binary number in your array, you have an ASCII string. Yet, you try to decode it as binary. Note there's no need to validate any input (maybe except the length) if you were dealing with binary number, as all single byte values are valid.

@Ainar-G gave you a way of converting ASCII number into integer.

Compare these two approaches: (http://play.golang.org/p/_wufZ4P_aE)

buf := []byte{54, 54, 49, 49}

x, _ := strconv.Atoi(string(buf))
fmt.Println(x)

This prints 6611; but look at this:

var y int32
_ = binary.Read(bytes.NewReader(buf), binary.BigEndian, &y)
fmt.Println(y)

This prints 909521201, so exactly what you got (and didn't expect). As a side note, you're manually decoding it as BigEndian, so this is not "such a simple conversion" at the end, because there're some more factors to consider.

Your handcrafted conversion from ASCII would look more or less as follows:

var x int32
for _, c := range in {
    x = x*10 + int32(c - '0')
}
return x

But using strconv is the way to go.

Sign up to request clarification or add additional context in comments.

Comments

2

Convert your bytes to string and use strconv.Atoi.

b := []byte{54, 54, 49, 49}
s := string(b)
i, err := strconv.Atoi(s)
if err != nil {
    panic(err)
}
fmt.Println(i)

Playground: http://play.golang.org/p/NiobWHZ9gd

1 Comment

Thank you for answers. I got it working with these. Thinking about need for such conversion in GO, is it because GO is 'Strictly Typed' language, typecasts like those in C (typically using void *) are not possible here? Because byte array is similar to char*/char[] in C which is typically used as send/recv buffer.
1

Adding to @tomasz's answer, if you want to store a number in a binary format and don't care about endianess you can use pointers:

b := []byte{239, 190, 173, 222}
v := *(*uint32)(unsafe.Pointer(&b[0]))
fmt.Printf("0x%X\n", v)
fmt.Printf("%v", *(*[4]byte)(unsafe.Pointer(&v)))

playground

Comments

1

If all you need is to convert a simple positive int value that comes in a []byte, like in this example []byte{'6', '6', '1', '1'} or []byte{54, 54, 49, 49} (which is the same), a very simple for loop on the []byte adding to an int, will do the trick, just like this:

var (
    myInt, i int
    myBytes = []byte{'6', '6', '1', '1'}
    v byte
)
for ; i < len(myBytes); i++ {
            v = myBytes[i] - '0'
            myInt *= 10
            myInt += int(v)
}

...and that's all.

See the full working code in the Playground

2 Comments

Can you please elaborate how v = myBytes[i] - '0' is calculated? What this actually do? Thanks
Sure, if you see an ASCII table this will become clear to you. subtracting ASCII '0' (48 decimal) reduces 48 from the byte value. In the example above ASCII '6' is actually byte 54, if you move the byte direct to v it will have the decimal value 54 of the byte but you are looking for the int value 6 not 54 right? then you have to subtract the zero value for it (ASCII '0' - decimal 48) 54-48=6 this is the int. value for the byte 54, play in the playground a little bit and it will become clearer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.