Mohsen
Mohsen

Reputation: 4266

Convert float64 to byte array

How can I convert a float64 variable to big endian encoded byte array?

var f float64 = 12.666512
var result []byte = float64ToByte(f);
fmt.Printf("result:%f",result)

For the sake of clarity how should I implement float64ToByte function in the following playground?

https://play.golang.org/p/LevxCDd7mK

Upvotes: 15

Views: 22561

Answers (4)

jeremie
jeremie

Reputation: 1131

Adding yet another flavor to this question.

func float64ToBytes(f64 float64) []byte {
    bts := make([]byte, 8)
    (*(*[]float64)(unsafe.Pointer(&bts)))[0] = f64
    return bts
}

func bytesToF64(bts []byte) float64 {
    return *(*float64)(unsafe.Pointer(&bts[0]))
}

You could even make it with zero allocation like this

func float64ToBytes(f64 float64) []byte {
    var bts []byte
    sh := (*reflect.SliceHeader)(unsafe.Pointer(&bts))
    sh.Data = uintptr(unsafe.Pointer(&f64))
    sh.Len = 8
    sh.Cap = sh.Len
    return bts
}

Upvotes: 1

slaxor
slaxor

Reputation: 516

https://play.golang.org/p/FO32EmWfjbL

On my system it had to be little endianed:

func float64ToByte(f float64) []byte {
    var buf bytes.Buffer
    err := binary.Write(&buf, binary.LittleEndian, f)
    if err != nil {
        fmt.Println("binary.Write failed:", err)
    }
    return buf.Bytes()
}

Upvotes: 0

har07
har07

Reputation: 89325

You can use binary.Write() from package "encoding/binary" :

func float64ToByte(f float64) []byte {
    var buf bytes.Buffer
    err := binary.Write(&buf, binary.BigEndian, f)
    if err != nil {
        fmt.Println("binary.Write failed:", err)
    }
    return buf.Bytes()
}

https://play.golang.org/p/XcvM5eaGtU

Upvotes: 13

Thundercat
Thundercat

Reputation: 121119

Use math.Float64bits to get the float64 as a uint64. Use shifting and conversions on the uint64 to convert to a desired sequence of bytes. For example, here's how to encode a float in big endian order:

var buf [8]byte
n := math.Float64bits(f)
buf[0] = byte(n >> 56)
buf[1] = byte(n >> 48)
buf[2] = byte(n >> 40)
buf[3] = byte(n >> 32)
buf[4] = byte(n >> 24)
buf[5] = byte(n >> 16)
buf[6] = byte(n >> 8)
buf[7] = byte(n)

You can use the encoding/binary to convert the uint64 to bytes instead of writing out the shifts and conversions directly. Here's how to encode the float64 in big endian order using that package:

var buf [8]byte
binary.BigEndian.PutUint64(buf[:], math.Float64bits(f))

The little endian code is:

var buf [8]byte
binary.LittleEndian.PutUint64(buf[:], math.Float64bits(f))

Here's the big endian implementation of the float64ToByte function in the question:

func float64ToByte(f float64) []byte {
   var buf [8]byte
   binary.BigEndian.PutUint64(buf[:], math.Float64bits(f))
   return buf[:]
}

playground example

Upvotes: 26

Related Questions