uint256: Add bit length support.
This adds support for determining the minimum number of bits required to represent the current value of a uint256 along with associated tests to ensure proper functionality. This is part of a series of commits to fully implement the uint256 package.
This commit is contained in:
parent
7ba863dff6
commit
c0854f6f17
@ -26,11 +26,11 @@ var (
|
||||
// subtraction, multiplication, squaring, division, negation), bitwise
|
||||
// operations (lsh, rsh, not, or, and, xor), comparison operations (equals,
|
||||
// less, greater, cmp), interpreting and producing big and little endian bytes,
|
||||
// and other convenience methods such as whether or not the value can be
|
||||
// and other convenience methods such as determining the minimum number of bits
|
||||
// required to represent the current value and whether or not the value can be
|
||||
// represented as a uint64 without loss of precision.
|
||||
//
|
||||
// Future commits will implement other convenience methods such as determining
|
||||
// the minimum number of bits required to represent the current value and text
|
||||
// Future commits will implement other convenience methods such as text
|
||||
// formatting with base conversion.
|
||||
type Uint256 struct {
|
||||
// The uint256 is represented as 4 unsigned 64-bit integers in base 2^64.
|
||||
@ -1326,3 +1326,18 @@ func (n *Uint256) Xor(n2 *Uint256) *Uint256 {
|
||||
n.n[3] ^= n2.n[3]
|
||||
return n
|
||||
}
|
||||
|
||||
// BitLen returns the minimum number of bits required to represent the uint256.
|
||||
// The result is 0 when the value is 0.
|
||||
func (n *Uint256) BitLen() uint16 {
|
||||
if w := n.n[3]; w > 0 {
|
||||
return uint16(bits.Len64(w)) + 192
|
||||
}
|
||||
if w := n.n[2]; w > 0 {
|
||||
return uint16(bits.Len64(w)) + 128
|
||||
}
|
||||
if w := n.n[1]; w > 0 {
|
||||
return uint16(bits.Len64(w)) + 64
|
||||
}
|
||||
return uint16(bits.Len64(n.n[0]))
|
||||
}
|
||||
|
||||
@ -3320,3 +3320,80 @@ func TestUint256XorRandom(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestUint256BitLen ensures determining the minimum number of bits required to
|
||||
// represent a uint256 works as expected.
|
||||
func TestUint256BitLen(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string // test description
|
||||
n string // hex encoded value
|
||||
want uint16 // expected result
|
||||
}{{
|
||||
name: "zero",
|
||||
n: "0",
|
||||
want: 0,
|
||||
}, {
|
||||
name: "one",
|
||||
n: "1",
|
||||
want: 1,
|
||||
}, {
|
||||
name: "two",
|
||||
n: "2",
|
||||
want: 2,
|
||||
}, {
|
||||
name: "2^32 - 1",
|
||||
n: "ffffffff",
|
||||
want: 32,
|
||||
}, {
|
||||
name: "2^32",
|
||||
n: "100000000",
|
||||
want: 33,
|
||||
}, {
|
||||
name: "2^64 - 2",
|
||||
n: "fffffffffffffffe",
|
||||
want: 64,
|
||||
}, {
|
||||
name: "2^64 - 1",
|
||||
n: "ffffffffffffffff",
|
||||
want: 64,
|
||||
}, {
|
||||
name: "2^64",
|
||||
n: "10000000000000000",
|
||||
want: 65,
|
||||
}, {
|
||||
name: "2^128 - 1",
|
||||
n: "ffffffffffffffffffffffffffffffff",
|
||||
want: 128,
|
||||
}, {
|
||||
name: "2^128",
|
||||
n: "100000000000000000000000000000000",
|
||||
want: 129,
|
||||
}, {
|
||||
name: "2^192 - 1",
|
||||
n: "ffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
want: 192,
|
||||
}, {
|
||||
name: "2^192",
|
||||
n: "1000000000000000000000000000000000000000000000000",
|
||||
want: 193,
|
||||
}, {
|
||||
name: "2^255 - 1",
|
||||
n: "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
want: 255,
|
||||
}, {
|
||||
name: "2^256 - 1",
|
||||
n: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
want: 256,
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
got := hexToUint256(test.n).BitLen()
|
||||
if got != test.want {
|
||||
t.Errorf("%q: wrong result -- got: %v, want: %v", test.name, got,
|
||||
test.want)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user