Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have a data stream of bytes and I'd like to get a little endian encoded int32 from four bytes. Is there a better way than to do this like the following code?

package main

func read_int32(data []byte) int32 {
    return int32(uint32(data[0]) + uint32(data[1])<<8 + uint32(data[2])<<16 + uint32(data[3])<<24)
}

func main() {
    println(read_int32([]byte{0xFE,0xFF,0xFF,0xFF})) // -2
    println(read_int32([]byte{0xFF,0x00,0x00,0x00})) // 255
}

The code above seems to work fine, but perhaps there is a built-in function in Go that I've missed or there is a super cool hack that does that in one instruction?

share|improve this question
    
This page should help. golang.org/pkg/encoding/binary/#ReadVarint –  Larry Battle Sep 26 '12 at 7:10

2 Answers 2

encoding/binary package may have what you need. Check this: http://golang.org/pkg/encoding/binary/#example_Read

Your code with modified read_int32 function could be:

package main
import (
    "bytes"
    "encoding/binary"
    "fmt"
)

func read_int32(data []byte) (ret int32) {
    buf := bytes.NewBuffer(data)
    binary.Read(buf, binary.LittleEndian, &ret)
    return
}

func main() {
    fmt.Println(read_int32([]byte{0xFE, 0xFF, 0xFF, 0xFF})) // -2
    fmt.Println(read_int32([]byte{0xFF, 0x00, 0x00, 0x00})) // 255
}

Also you can interpret big endian by replacing binary.LittleEndian with binary.BigEndian

share|improve this answer
    
That looks fine, I'll try it out and report back. Thanks! –  topskip Nov 3 '12 at 7:29

This is a really late answer, however there are 2 different ways to do it.

func readInt32(b []byte) int32 {
    // equivalnt of return int32(binary.LittleEndian.Uint32(b))
    return int32(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
}

// this is much faster and more efficient, however it won't work on appengine 
// since it doesn't have the unsafe package.
// Also this would blow up silently if len(b) < 4.
func ReadInt32Unsafe(b []byte) int32 {
    return *(*int32)(unsafe.Pointer(&b[0]))
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.