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 }