I have an id that is represented at an int64. How can I convert this to a []byte? I see that the binary package does this for uints, but I want to make sure I don't break negative numbers.
6 Answers
Converting between int64 and uint64 doesn't change the sign bit, only the way it's interpreted.
You can use Uint64 and PutUint64 with the correct ByteOrder
http://play.golang.org/p/wN3ZlB40wH
i := int64(-123456789)
fmt.Println(i)
b := make([]byte, 8)
binary.LittleEndian.PutUint64(b, uint64(i))
fmt.Println(b)
i = int64(binary.LittleEndian.Uint64(b))
fmt.Println(i)
output:
-123456789
[235 50 164 248 255 255 255 255]
-123456789
2 Comments
PutUint64 uses fixed length encoding. You only need MaxVarintLenXX when using PutVarint.If you don't care about the sign or endianness (for example, reasons like hashing keys for maps etc), you can simply shift bits, then AND them with 0b11111111 (0xFF):
(assume v is an int32)
b := [4]byte{
byte(0xff & v),
byte(0xff & (v >> 8)),
byte(0xff & (v >> 16)),
byte(0xff & (v >> 24))}
(for int64/uint64, you'd need to have a byte slice of length 8)
4 Comments
int64/uint64 uses 8 Bytes of storage. int32/uint32 only uses 4 Bytes.The code:
var num int64 = -123456789
// convert int64 to []byte
buf := make([]byte, binary.MaxVarintLen64)
n := binary.PutVarint(buf, num)
b := buf[:n]
// convert []byte to int64
x, n := binary.Varint(b)
fmt.Printf("x is: %v, n is: %v\n", x, n)
outputs
x is: -123456789, n is: 4
2 Comments
You can use this too:
var num int64 = -123456789
b := []byte(strconv.FormatInt(num, 10))
fmt.Printf("num is: %v, in string is: %s", b, string(b))
Output:
num is: [45 49 50 51 52 53 54 55 56 57], in string is: -123456789
1 Comment
If you need a similar function as int.to_bytes(length, byteorder, *, signed=False) in Go you can do this:
func uint64ToLenBytes(v uint64, l int) (b []byte) {
b = make([]byte, l)
for i := 0; i < l; i++ {
f := 8 * i
b[i] = byte(v >> f)
}
return
}
func int64ToLenBytes(v int64, l int) (b []byte) {
return uint64ToLenBytes(uint64(v), l)
}
It will return a slice of bytes, for example:
ba = int64ToLenBytes(258, 3)
fmt.Printf("%#v\n", ba)
// output:
[]byte{0x2, 0x1, 0x0}
Comments
Here's a simple function that should accomplish what you are wanting:
func Int64ToBytes(number int64) []byte {
big := new(big.Int)
big.SetInt64(number)
return big.Bytes()
}
intoruintis just how CPU "interprets" the underlying bits. The underlying bits(11100101...) in the memory remain the same. If it'suint, the interpreting is straightforward. But if it'sint, there are several ways to interpret/represent negative numbers from/to bits (two's complement is a popular way).