2018-09-18 02:36:09 +00:00
|
|
|
package shared
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math"
|
|
|
|
|
|
|
|
"github.com/steakknife/hamming"
|
|
|
|
)
|
2018-08-14 00:58:37 +00:00
|
|
|
|
|
|
|
// CheckBit checks if a bit in a bit field is one.
|
2018-08-24 16:07:23 +00:00
|
|
|
func CheckBit(bitfield []byte, index int) bool {
|
2018-08-14 00:58:37 +00:00
|
|
|
chunkLocation := (index + 1) / 8
|
|
|
|
indexLocation := (index + 1) % 8
|
|
|
|
if indexLocation == 0 {
|
|
|
|
indexLocation = 8
|
|
|
|
} else {
|
|
|
|
chunkLocation++
|
|
|
|
}
|
|
|
|
|
|
|
|
field := bitfield[chunkLocation-1] >> (8 - uint(indexLocation))
|
2018-08-24 16:07:23 +00:00
|
|
|
return field%2 != 0
|
2018-08-14 00:58:37 +00:00
|
|
|
}
|
|
|
|
|
2018-09-20 14:56:51 +00:00
|
|
|
// BitSetCount counts the number of 1s in a byte using Hamming weight.
|
|
|
|
// See: https://en.wikipedia.org/wiki/Hamming_weight
|
|
|
|
func BitSetCount(b []byte) int {
|
|
|
|
return hamming.CountBitsBytes(b)
|
2018-08-14 00:58:37 +00:00
|
|
|
}
|
2018-08-24 16:07:23 +00:00
|
|
|
|
2018-09-18 02:36:09 +00:00
|
|
|
// BitLength returns the length of the bitfield in bytes.
|
2018-08-24 16:07:23 +00:00
|
|
|
func BitLength(b int) int {
|
|
|
|
return (b + 7) / 8
|
|
|
|
}
|
2018-09-18 02:36:09 +00:00
|
|
|
|
|
|
|
// SetBitfield takes an index and returns bitfield with the index flipped.
|
|
|
|
func SetBitfield(index int) []byte {
|
|
|
|
chunkLocation := index / 8
|
|
|
|
indexLocation := math.Pow(2, 7-float64(index%8))
|
|
|
|
var bitfield []byte
|
|
|
|
|
|
|
|
for i := 0; i < chunkLocation; i++ {
|
|
|
|
bitfield = append(bitfield, byte(0))
|
|
|
|
}
|
|
|
|
bitfield = append(bitfield, byte(indexLocation))
|
|
|
|
|
|
|
|
return bitfield
|
|
|
|
}
|