dongzhitao4839 2019-02-02 19:11
浏览 1014

在Golang中将大小可变的[] byte转换为int64

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]

  • 写回答

1条回答 默认 最新

  • dpdyh86002 2019-02-02 21:03
    关注

    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
    
    评论

报告相同问题?

悬赏问题

  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘