go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/fu/bits.go (about)

     1  package fu
     2  
     3  import (
     4  	"math/bits"
     5  )
     6  
     7  type Bits struct {
     8  	b []uint
     9  }
    10  
    11  const (
    12  	_W = bits.UintSize // word size in bits
    13  )
    14  
    15  func (q *Bits) Set(i int, v bool) {
    16  	j := i / _W
    17  	c := j + 1
    18  	n := len(q.b)
    19  	if !v && n < c {
    20  		return
    21  	}
    22  	if n < c {
    23  		x := make([]uint, c)
    24  		if n > 0 {
    25  			copy(x[:n], q.b)
    26  		}
    27  		q.b = x
    28  	}
    29  	m := uint(1) << (i % _W)
    30  	if v {
    31  		q.b[j] |= m
    32  	} else {
    33  		q.b[j] &= ^m
    34  	}
    35  }
    36  
    37  func (q *Bits) Or_(a Bits) {
    38  	if a.Len() > q.Len() {
    39  		*q = q.Grow(a.Len())
    40  	}
    41  	for i, x := range a.b {
    42  		q.b[i] |= x
    43  	}
    44  }
    45  
    46  func (q Bits) Bit(i int) bool {
    47  	j := int(i / _W)
    48  	m := uint(1) << (i % _W)
    49  	n := len(q.b)
    50  	if j >= n {
    51  		return false
    52  	}
    53  	return (q.b[j] & m) != 0
    54  }
    55  
    56  func (q Bits) Slice(from, to int) Bits {
    57  	ql := q.Len()
    58  	if ql <= from {
    59  		return Bits{}
    60  	}
    61  	if to > ql {
    62  		to = ql
    63  	}
    64  	c := ((to - from + _W - 1) / _W)
    65  	x := make([]uint, c)
    66  	rr := from % _W
    67  	rl := _W - rr
    68  	of := from / _W
    69  	for i := range x {
    70  		x[i] = q.b[i+of] >> rr
    71  		if i+1 < len(q.b) {
    72  			x[i] |= q.b[i+of+1] << rl
    73  		}
    74  	}
    75  	x[len(x)-1] &= ^uint(0) >> (_W - ((to - from) % _W))
    76  	r := Bits{x}
    77  	if r.Len() == 0 {
    78  		return Bits{}
    79  	}
    80  	return r
    81  }
    82  
    83  func (q Bits) Len() int {
    84  	L := len(q.b) - 1
    85  	for i := range q.b {
    86  		if l := bits.Len(q.b[L-i]); l != 0 {
    87  			return (L-i)*_W + l
    88  		}
    89  	}
    90  	return 0
    91  }
    92  
    93  func (q Bits) Copy() Bits {
    94  	if q.Len() == 0 {
    95  		return Bits{}
    96  	}
    97  	c := (q.Len() + _W - 1) / _W
    98  	r := make([]uint, c)
    99  	copy(r, q.b[:c])
   100  	return Bits{r}
   101  }
   102  
   103  func (q Bits) Grow(cap int) Bits {
   104  	c := (cap + _W - 1) / _W
   105  	if len(q.b) >= c {
   106  		return q.Copy()
   107  	}
   108  	r := make([]uint, c)
   109  	copy(r[:len(q.b)], q.b)
   110  	return Bits{r}
   111  }
   112  
   113  func (q Bits) Append(z Bits, at int) Bits {
   114  	if at < q.Len() {
   115  		panic("bits overflow")
   116  	}
   117  	zl := z.Len()
   118  	if z.Len() == 0 {
   119  		return q.Copy()
   120  	}
   121  	w := q.Grow(at + zl)
   122  	k := (zl + _W - 1) / _W
   123  	j := at / _W
   124  	ll := at % _W
   125  	rl := _W - ll
   126  	for i := 0; i < k; i++ {
   127  		w.b[j+i] |= z.b[i] << ll
   128  		x := z.b[i] >> rl
   129  		if rl != _W && x != 0 {
   130  			w.b[j+i+1] |= z.b[i] >> rl
   131  		}
   132  	}
   133  	return w
   134  }
   135  
   136  func FillBits(count int) Bits {
   137  	if count == 0 {
   138  		return Bits{}
   139  	}
   140  
   141  	L := (count + _W - 1) / _W
   142  	r := make([]uint, L)
   143  	v := ^uint(0)
   144  	if count < _W {
   145  		v = v >> (_W - count)
   146  		r[0] = v
   147  	} else {
   148  		for i := 0; i < count/_W; i++ {
   149  			r[i] = v
   150  		}
   151  		if count%_W != 0 {
   152  			r[count/_W] = v >> (_W - count%_W)
   153  		}
   154  	}
   155  	return Bits{r}
   156  }
   157  
   158  func (q Bits) Repr() string {
   159  	n := q.Len()
   160  	b := make([]byte, n)
   161  	for i := 0; i < n; i++ {
   162  		c := byte('0')
   163  		if (q.b[i/_W]>>(i%_W))&1 != 0 {
   164  			c = byte('1')
   165  		}
   166  		b[i] = c
   167  	}
   168  	return string(b)
   169  }
   170  
   171  func (q Bits) String() string {
   172  	n := q.Len()
   173  	b := make([]byte, n+n/8)
   174  	for i, j := 0, 0; i < n; i++ {
   175  		if i != 0 && i%8 == 0 {
   176  			b[j] = byte('.')
   177  			j++
   178  		}
   179  		c := byte('0')
   180  		if (q.b[i/_W]>>(i%_W))&1 != 0 {
   181  			c = byte('1')
   182  		}
   183  		b[j] = c
   184  		j++
   185  	}
   186  	return string(b)
   187  }
   188  
   189  func Words(l int) int {
   190  	return (l + _W - 1) / _W
   191  }
   192  
   193  func (q Bits) Word(i int) uint {
   194  	if i < len(q.b) {
   195  		return q.b[i]
   196  	}
   197  	return 0
   198  }
   199  
   200  func (q Bits) Count() (n int) {
   201  	for _, x := range q.b {
   202  		n += bits.OnesCount(x)
   203  	}
   204  	return
   205  }