Skip to content

Commit

Permalink
go.tools/container/intsets: support negative elements in BitString().
Browse files Browse the repository at this point in the history
(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
  • Loading branch information
adonovan committed May 20, 2014
1 parent c0060ec commit 65906ce
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 14 deletions.
33 changes: 29 additions & 4 deletions container/intsets/sparse.go
Original file line number Diff line number Diff line change
Expand Up @@ -698,19 +698,44 @@ func (s *Sparse) String() string {
return buf.String()
}

// BitString returns the set s as a non-empty string of 1s and 0s.
// The ith character is 1 if the set contains i.
// BitString returns the set as a string of 1s and 0s denoting the sum
// 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 {
if s.IsEmpty() {
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 {
b[i] = '0'
}
if radix < nbytes {
b[radix] = '.'
}
s.forEach(func(x int) {
b[x] = '1'
if x >= 0 {
x += len(".")
}
b[radix-x] = '1'
})
return string(b)
}
Expand Down
28 changes: 18 additions & 10 deletions container/intsets/sparse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ func TestBasics(t *testing.T) {
if s := s.String(); 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) {
t.Errorf("Has(3): got true, want false")
}
Expand Down Expand Up @@ -421,13 +418,24 @@ func TestIntersectionWith(t *testing.T) {
}

func TestBitString(t *testing.T) {
var set intsets.Sparse
set.Insert(0)
set.Insert(7)
set.Insert(177)
want := "10000001" + strings.Repeat("0", 169) + "1"
if got := set.BitString(); got != want {
t.Errorf("BitString: got %s, want %s", got, want)
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
for _, x := range test.input {
set.Insert(x)
}
if got := set.BitString(); got != test.want {
t.Errorf("BitString(%s) = %s, want %s", set.String(), got, test.want)
}
}
}

Expand Down

0 comments on commit 65906ce

Please sign in to comment.