How do you convert array of byte to array of float64 - go

I am searching to convert an array of byte ([]byte) to array of float64 ([]float64) but I didn't have any clues to do it.
I read data from rtlsdr package (https://pkg.go.dev/github.com/jpoirier/gortlsdr) and would pass it to Pwelch algorithm (https://pkg.go.dev/github.com/mjibson/go-dsp/spectral)
Is it possible to convert large array of byte to float64 ?
(+ another question: did you think that possible to convert Pwelch function to work with uint8 ?)
Thank you so much,
pefr

byte/uint8 has 8 bits, float64 has 64. You can convert [8]byte to float64 like this:
package main
import (
"encoding/binary"
"fmt"
"math"
)
main()
{
in := 1.
// Convert float64 to [8]byte
var bytes [8]byte
binary.LittleEndian.PutUint64(bytes[:], math.Float64bits(in))
// Convert [8]byte to float64
out := math.Float64frombits(binary.LittleEndian.Uint64(bytes[:]))
fmt.Println(out)
}
You may want to chose binary.BigEndian instead.
Is that what you are looking for? Or do you want to convert an array of byte with length 8n to an array of float64 with length n? Feel free to comment :-)

Related

Printing type of the numeric constant causes overflow

I am new to Go and currently following A Tour of Go.
I am currently at page Numeric Constants. Down below is a trimmed down version of the code that runs on that page:
package main
import "fmt"
const Big = 1 << 100
func needFloat(x float64) float64 {
return x * 0.1
}
func main() {
fmt.Println(needFloat(Big))
// fmt.Printf("Type of Big %T", Big)
}
this code compiles successfully with the output 1.2676506002282295e+29
The following code however will not compile and give an error:
package main
import "fmt"
const Big = 1 << 100
func needFloat(x float64) float64 {
return x * 0.1
}
func main() {
fmt.Println(needFloat(Big))
fmt.Printf("Type of Big %T", Big)
}
Output:
./prog.go:9:13: constant 1267650600228229401496703205376 overflows int
Why do you think this happened? I hope you will kindly explain.
The constant Big is an untyped constant. An untyped constant can be arbitrarily large and it doesn't have to fit into any predefined type's limits. It is interpreted and truncated in the context it is used.
The function needFloat gets a float64 argument. At this instance Big is converted to a float64 and used that way.
When you use it for Printf, it tries to pass it in as an int because it is not a decimal number (otherwise it would've converted it to float64), and it causes an overflow. Pass it as float64(Big), and it should work.
I guess the reason is that Big gets computed (i.e. casted right before being passed to needFloat, and gets instead computed as a int64 before the Printf. As a proof, the following statement computes correctly:
package main
import "fmt"
const Big = 1 << 100
func main() {
fmt.Printf("Type of Big %T", float64(Big))
}
Hope this helps.
The untyped constant n must be converted to a type before it can be assigned to the interface{} parameter in the call to fmt.Println.
fmt.Println(a ...interface{})
When the type can’t be inferred from the context, an untyped constant is converted to a bool, int, float64, complex128, string or rune depending of the format of the constant.
In this case the constant is an integer, but n is larger than the maximum value of an int.
However, n can be represented as a float64.
const n = 9876543210 * 9876543210
fmt.Println(float64(n))
For exact representation of big numbers, the math/big package implements arbitrary-precision arithmetic. It supports signed integers, rational numbers and floating-point numbers.
This is taken from https://yourbasic.org/golang/gotcha-constant-overflows-int/.

How to get an integer result from the math floor function in golang?

The math.Floor in Golang returns a float64. But I would like it to return an integer. How can I get the integer value after performing the floor operation? Can I just use int(x) or int32(x) or int64(x)? I worry that the integer range might not match that of a float64 result therefore brings inaccuracy to the operation.
You may just want to check beforehand; if the conversion will perform safely or an overflow will occur.
As John Weldon suggested,
package main
import (
"fmt"
"math"
)
func main() {
var (
a int64
f64 float64
)
// This number doesn't exist in the float64 world,
// just a number to perform the test.
f64 = math.Floor(9223372036854775808.5)
if f64 >= math.MaxInt64 || f64 <= math.MinInt64 {
fmt.Println("f64 is out of int64 range.")
return
}
a = int64(f64)
fmt.Println(a)
}
Go Playground
I hope this will answer your question.
Also, I'd really like to know if any better solution is available. :)
You can compare the float64 value with math.MaxInt64 or math.MinInt64 before doing the conversion.

binary.Write() byte ordering not working for []byte

package main
import (
"encoding/binary"
"fmt"
"bytes"
)
func main(){
b := new(bytes.Buffer)
c := new(bytes.Buffer)
binary.Write(b, binary.LittleEndian, []byte{0, 1})
binary.Write(b, binary.BigEndian, []byte{0, 1})
binary.Write(c, binary.LittleEndian, uint16(256))
binary.Write(c, binary.BigEndian, uint16(256))
fmt.Println(b.Bytes()) // [0 1 0 1]
fmt.Println(c.Bytes()) // [0 1 1 0]
}
It is very interesting, why binary.Write() byte ordering is working for uint8, uint16, uint64..etc, but []byte?
If []byte need to be ordered by binary.LittleEndian and write to bytes.Buffer, it needs to be reversed first? Is there any effective ways to solve this problem?
Thanks.
Only integer types get swapped by byte ordering.
When it's a slice of bytes, the binary package wouldn't really know what to swap.
For example, how would it know what to do if you passed 1k of data?
Treat it as int16, int32 or int64?
Or would you expect it to just reverse the whole slice?
Because there is nothing to order by. A byte is 8 bits, so you can go (unsigned) from 0 to 255. ie. uint16 you have 2 bytes, so you can order them differently.
ByteOrder is not even defined for int8. You can check the source code to see that binary.Write simply not uses the passed order when types are uint8 or int8. (A byte is an alias to uint8)

Size of a byte array golang

I have a []byte object and I want to get the size of it in bytes. Is there an equivalent to C's sizeof() in golang? If not, Can you suggest other ways to get the same?
To return the number of bytes in a byte slice use the len function:
bs := make([]byte, 1000)
sz := len(bs)
// sz == 1000
If you mean the number of bytes in the underlying array use cap instead:
bs := make([]byte, 1000, 2000)
sz := cap(bs)
// sz == 2000
A byte is guaranteed to be one byte: https://golang.org/ref/spec#Size_and_alignment_guarantees.
I think your best bet would be;
package main
import "fmt"
import "encoding/binary"
func main() {
thousandBytes := make([]byte, 1000)
tenBytes := make([]byte, 10)
fmt.Println(binary.Size(tenBytes))
fmt.Println(binary.Size(thousandBytes))
}
https://play.golang.org/p/HhJif66VwY
Though there are many options, like just importing unsafe and using sizeof;
import unsafe "unsafe"
size := unsafe.Sizeof(bytes)
Note that for some types, like slices, Sizeof is going to give you the size of the slice descriptor which is likely not what you want. Also, bear in mind the length and capacity of the slice are different and the value returned by binary.Size reflects the length.

Displayed size of Go string variable seems unreal

Please see the example: http://play.golang.org/p/6d4uX15EOQ
package main
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
c := "foofoofoofoofoofofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo"
fmt.Printf("c: %T, %d\n", c, unsafe.Sizeof(c))
fmt.Printf("c: %T, %d\n", c, reflect.TypeOf(c).Size())
}
Output:
c: string, 8 //8 bytes?!
c: string, 8
It seems like so large string can not have so small size! What's going wrong?
Package unsafe
import "unsafe"
func Sizeof
func Sizeof(v ArbitraryType) uintptr
Sizeof returns the size in bytes occupied by the value v. The size is
that of the "top level" of the value only. For instance, if v is a
slice, it returns the size of the slice descriptor, not the size of
the memory referenced by the slice.
The Go Programming Language Specification
Length and capacity
len(s) string type string length in bytes
You are looking at the "top level", the string descriptor, a pointer to and the length of the underlying string value. Use the len function for the length, in bytes, of the underlying string value.
Conceptually and practically, the string descriptor is a struct containing a pointer and a length, whose lengths (32 or 64 bit) are implementation dependent. For example,
package main
import (
"fmt"
"unsafe"
)
type stringDescriptor struct {
str *byte
len int
}
func main() {
fmt.Println("string descriptor size in bytes:", unsafe.Sizeof(stringDescriptor{}))
}
Output (64 bit):
string descriptor size in bytes: 16
Output (32 bit):
string descriptor size in bytes: 8
A string is essentially a pointer the the data, and an int for the length; so on 32bit systems, it's 8 bytes, and 16 bytes on 64-bit systems.
Both unsafe.Sizeof and reflect.TypeOf(foo).Size() show the size of the string header (two words, IIRC). If you want to get the length of a string, use len(foo).
Playground: http://play.golang.org/p/hRw-EIVIQg.

Resources