go.tools/container/intsets: support negative elements in BitString().
(I forgot about this when we added support for negative elements generally.) We use floating point for negative numbers. The order of the output is reversed from the previous (little-endian) behaviour since it makes for more readable floating point. LGTM=gri R=gri CC=golang-codereviews https://golang.org/cl/95570043
This commit is contained in:
parent
c0060eca2c
commit
65906ce503
|
@ -698,19 +698,44 @@ func (s *Sparse) String() string {
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BitString returns the set s as a non-empty string of 1s and 0s.
|
// BitString returns the set as a string of 1s and 0s denoting the sum
|
||||||
// The ith character is 1 if the set contains i.
|
// of the i'th powers of 2, for each i in s. A radix point, always
|
||||||
|
// preceded by a digit, appears if the sum is non-integral.
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
// {}.BitString() = "0"
|
||||||
|
// {4,5}.BitString() = "110000"
|
||||||
|
// {-3}.BitString() = "0.001"
|
||||||
|
// {-3,0,4,5}.BitString() = "110001.001"
|
||||||
//
|
//
|
||||||
func (s *Sparse) BitString() string {
|
func (s *Sparse) BitString() string {
|
||||||
if s.IsEmpty() {
|
if s.IsEmpty() {
|
||||||
return "0"
|
return "0"
|
||||||
}
|
}
|
||||||
b := make([]byte, s.Max()+1)
|
|
||||||
|
min, max := s.Min(), s.Max()
|
||||||
|
var nbytes int
|
||||||
|
if max > 0 {
|
||||||
|
nbytes = max
|
||||||
|
}
|
||||||
|
nbytes++ // zero bit
|
||||||
|
radix := nbytes
|
||||||
|
if min < 0 {
|
||||||
|
nbytes += len(".") - min
|
||||||
|
}
|
||||||
|
|
||||||
|
b := make([]byte, nbytes)
|
||||||
for i := range b {
|
for i := range b {
|
||||||
b[i] = '0'
|
b[i] = '0'
|
||||||
}
|
}
|
||||||
|
if radix < nbytes {
|
||||||
|
b[radix] = '.'
|
||||||
|
}
|
||||||
s.forEach(func(x int) {
|
s.forEach(func(x int) {
|
||||||
b[x] = '1'
|
if x >= 0 {
|
||||||
|
x += len(".")
|
||||||
|
}
|
||||||
|
b[radix-x] = '1'
|
||||||
})
|
})
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,6 @@ func TestBasics(t *testing.T) {
|
||||||
if s := s.String(); s != "{}" {
|
if s := s.String(); s != "{}" {
|
||||||
t.Errorf("String({}): got %q, want \"{}\"", s)
|
t.Errorf("String({}): got %q, want \"{}\"", s)
|
||||||
}
|
}
|
||||||
if s := s.BitString(); s != "0" {
|
|
||||||
t.Errorf("BitString({}): got %q, want \"0\"", s)
|
|
||||||
}
|
|
||||||
if s.Has(3) {
|
if s.Has(3) {
|
||||||
t.Errorf("Has(3): got true, want false")
|
t.Errorf("Has(3): got true, want false")
|
||||||
}
|
}
|
||||||
|
@ -421,13 +418,24 @@ func TestIntersectionWith(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBitString(t *testing.T) {
|
func TestBitString(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
input []int
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{nil, "0"},
|
||||||
|
{[]int{0}, "1"},
|
||||||
|
{[]int{0, 4, 5}, "110001"},
|
||||||
|
{[]int{0, 7, 177}, "1" + strings.Repeat("0", 169) + "10000001"},
|
||||||
|
{[]int{-3, 0, 4, 5}, "110001.001"},
|
||||||
|
{[]int{-3}, "0.001"},
|
||||||
|
} {
|
||||||
var set intsets.Sparse
|
var set intsets.Sparse
|
||||||
set.Insert(0)
|
for _, x := range test.input {
|
||||||
set.Insert(7)
|
set.Insert(x)
|
||||||
set.Insert(177)
|
}
|
||||||
want := "10000001" + strings.Repeat("0", 169) + "1"
|
if got := set.BitString(); got != test.want {
|
||||||
if got := set.BitString(); got != want {
|
t.Errorf("BitString(%s) = %s, want %s", set.String(), got, test.want)
|
||||||
t.Errorf("BitString: got %s, want %s", got, want)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue