github.com/tunabay/go-bitarray@v1.3.1/bitarray_convert.go (about)

     1  // Copyright (c) 2021 Hirotsuna Mizuno. All rights reserved.
     2  // Use of this source code is governed by the MIT license that can be found in
     3  // the LICENSE file.
     4  
     5  package bitarray
     6  
     7  import (
     8  	"encoding/binary"
     9  	"math/big"
    10  )
    11  
    12  // NewFromInt creates a BitArray from big.Int. The returned bit array represents
    13  // the absolute value of v in big-endian byte order. For big.Int(0), it returns
    14  // a "0" instead of an empty bit array.
    15  func NewFromInt(v *big.Int) *BitArray {
    16  	nBits := v.BitLen()
    17  	if nBits == 0 {
    18  		return &BitArray{nBits: 1}
    19  	}
    20  
    21  	return NewFromBytes(v.Bytes(), (8-nBits&7)&7, nBits)
    22  }
    23  
    24  // ToInt parses the bit array as a big-endian representation, and convert it to
    25  // an unsigned integer value. The leading 0s have no effect on the result.
    26  func (ba *BitArray) ToInt() *big.Int {
    27  	v := big.NewInt(0)
    28  	if ba.IsZero() || ba.b == nil {
    29  		return v
    30  	}
    31  	v.SetBytes(ba.b)
    32  
    33  	return v.Rsh(v, uint(ba.NumPadding()))
    34  }
    35  
    36  // ToUint64 is the same as ToInt except that it returns uint64 instead of
    37  // *big.Int. If the bit array length exceeds 64 bits, only the last 64 bits
    38  // will be used.
    39  func (ba *BitArray) ToUint64() uint64 {
    40  	if ba.IsZero() || ba.b == nil {
    41  		return 0
    42  	}
    43  	switch {
    44  	case ba.nBits < 64:
    45  		buf := make([]byte, 8)
    46  		copy(buf[8-len(ba.b):], ba.b)
    47  		return binary.BigEndian.Uint64(buf) >> ba.NumPadding()
    48  	case 64 < ba.nBits:
    49  		ba = ba.Slice(ba.nBits-64, ba.nBits)
    50  	}
    51  
    52  	return binary.BigEndian.Uint64(ba.b)
    53  }