Reputation: 555
I have a method that transposes slice of int64 ([]int64) to a int64 but I haven't found a way to do it.
package main
import "fmt"
import "bytes"
import "encoding/binary"
func main() {
var mySlice = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 23}
data := binary.BigEndian.Uint64(mySlice)
fmt.Println(data)
var ret int64
buf := bytes.NewBuffer(mySlice)
binary.Read(buf, binary.BigEndian, ret)
fmt.Println(ret)
}
My method initializes []byte from a given size (say, make([]byte, 20)) and my method operates on a given bit and dimension size and interleaves it (bit operations):
So, say a []byte{0 0 0 0 0 0 0 0 0 23} gives 23 and a [more trailing zeroes..., 125, more tailing zeroes...] is 500
I guess I'm looking for something more like java's BigInteger class that takes in []byte (and signum) in BigEndian.
The method I'm trying to port (from Java) would be something like this:
BigInteger toIndex(long... transposedIndex) {
byte[] b = new byte[length];
int bIndex = length - 1;
long mask = 1L << (bits - 1);
for (int i = 0; i < bits; i++) {
for (int j = 0; j < transposedIndex.length; j++) {
if ((transposedIndex[j] & mask) != 0) {
b[length - 1 - bIndex / 8] |= 1 << (bIndex % 8);
}
bIndex--;
}
mask >>= 1;
}
// b is expected to be BigEndian
return new BigInteger(1, b);
}
and what I have in Golang is this:
func (s *TestStruct) untranspose(x []int64) (b int64) {
t := make([]byte, s.length)
bIndex := s.length - 1
mask := int64(1 << (s.bits - 1))
for i := 0; i < int(s.bits); i++ {
for j := 0; j < len(x); j++ {
if (x[j] & mask) != 0 {
t[s.length - 1 - bIndex / 8] |= 1 << (bIndex % 8)
}
bIndex--
}
mask >>= 1
}
return int64(binary.BigEndian.Uint64(t))
}
which doesn't seem to be correct. []byte could be longer than 8-bit, say, [0 0 0 0 0 0 0 0 2 170]
Upvotes: 1
Views: 13974
Reputation: 599
First, your slice is too long. Because of this, if each value represents a byte, then a 64-bit unsigned integer requires only 8 entries. The slice is read from front to back so in your sample the 23
entry is chopped off because it's the 10th entry.
Also, when reading from the buffer, you need to pass a reference as the last parameter (&ret
).
Lastly, you define ret
as a uint
which is 32-bits long where as the mySlice
defines a 64-bit integer (uint64
). This means that the last 32-bits of your slice will be cut off.
Below is a the working code for your sample and it's output:
package main
import "fmt"
import "bytes"
import "encoding/binary"
func main() {
var mySlice = []byte{0, 0, 0, 0, 0, 0, 0, 23}
data := binary.BigEndian.Uint64(mySlice)
fmt.Println(data)
var ret uint64
buf := bytes.NewBuffer(mySlice)
binary.Read(buf, binary.BigEndian, &ret)
fmt.Println(ret)
}
23
23
Upvotes: 6