Avoids an unnecessary heap allocation when computing the bit length of
int64 values.
Change-Id: I69dfc510e461daf3e83b0b7b6c0707f6526a32d0
Reviewed-on: https://go-review.googlesource.com/c/go/+/272646
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
"go/token"
"math"
"math/big"
+ "math/bits"
"strconv"
"strings"
"sync"
func BitLen(x Value) int {
switch x := x.(type) {
case int64Val:
- return i64toi(x).val.BitLen()
+ u := uint64(x)
+ if x < 0 {
+ u = uint64(-x)
+ }
+ return 64 - bits.LeadingZeros64(u)
case intVal:
return x.val.BitLen()
case unknownVal:
})
}
}
+
+var bitLenTests = []struct {
+ val int64
+ want int
+}{
+ {0, 0},
+ {1, 1},
+ {-16, 5},
+ {1 << 61, 62},
+ {1 << 62, 63},
+ {-1 << 62, 63},
+ {-1 << 63, 64},
+}
+
+func TestBitLen(t *testing.T) {
+ for _, test := range bitLenTests {
+ if got := BitLen(MakeInt64(test.val)); got != test.want {
+ t.Errorf("%v: got %v, want %v", test.val, got, test.want)
+ }
+ }
+}