mirror of
https://github.com/golang/go.git
synced 2025-05-23 00:11:26 +00:00
math/big: add IsInt64/IsUint64 predicates
Change-Id: Ia5ed3919cb492009ac8f66d175b47a69f83ee4f1 Reviewed-on: https://go-review.googlesource.com/36487 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
7bad00366b
commit
1f93ba66d6
@ -324,22 +324,22 @@ func (x *Int) Cmp(y *Int) (r int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// low32 returns the least significant 32 bits of z.
|
// low32 returns the least significant 32 bits of x.
|
||||||
func low32(z nat) uint32 {
|
func low32(x nat) uint32 {
|
||||||
if len(z) == 0 {
|
if len(x) == 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return uint32(z[0])
|
return uint32(x[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
// low64 returns the least significant 64 bits of z.
|
// low64 returns the least significant 64 bits of x.
|
||||||
func low64(z nat) uint64 {
|
func low64(x nat) uint64 {
|
||||||
if len(z) == 0 {
|
if len(x) == 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
v := uint64(z[0])
|
v := uint64(x[0])
|
||||||
if _W == 32 && len(z) > 1 {
|
if _W == 32 && len(x) > 1 {
|
||||||
v |= uint64(z[1]) << 32
|
return uint64(x[1])<<32 | v
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
@ -360,6 +360,20 @@ func (x *Int) Uint64() uint64 {
|
|||||||
return low64(x.abs)
|
return low64(x.abs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsInt64 reports whether x can be represented as an int64.
|
||||||
|
func (x *Int) IsInt64() bool {
|
||||||
|
if len(x.abs) <= 64/_W {
|
||||||
|
w := int64(low64(x.abs))
|
||||||
|
return w >= 0 || x.neg && w == -w
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsUint64 reports whether x can be represented as a uint64.
|
||||||
|
func (x *Int) IsUint64() bool {
|
||||||
|
return !x.neg && len(x.abs) <= 64/_W
|
||||||
|
}
|
||||||
|
|
||||||
// SetString sets z to the value of s, interpreted in the given base,
|
// SetString sets z to the value of s, interpreted in the given base,
|
||||||
// and returns z and a boolean indicating success. The entire string
|
// and returns z and a boolean indicating success. The entire string
|
||||||
// (not just a prefix) must be valid for success. If SetString fails,
|
// (not just a prefix) must be valid for success. If SetString fails,
|
||||||
|
@ -7,8 +7,8 @@ package big
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"testing/quick"
|
"testing/quick"
|
||||||
@ -903,56 +903,105 @@ func TestLshRsh(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var int64Tests = []int64{
|
var int64Tests = []string{
|
||||||
0,
|
// int64
|
||||||
1,
|
"0",
|
||||||
-1,
|
"1",
|
||||||
4294967295,
|
"-1",
|
||||||
-4294967295,
|
"4294967295",
|
||||||
4294967296,
|
"-4294967295",
|
||||||
-4294967296,
|
"4294967296",
|
||||||
9223372036854775807,
|
"-4294967296",
|
||||||
-9223372036854775807,
|
"9223372036854775807",
|
||||||
-9223372036854775808,
|
"-9223372036854775807",
|
||||||
|
"-9223372036854775808",
|
||||||
|
|
||||||
|
// not int64
|
||||||
|
"0x8000000000000000",
|
||||||
|
"-0x8000000000000001",
|
||||||
|
"38579843757496759476987459679745",
|
||||||
|
"-38579843757496759476987459679745",
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInt64(t *testing.T) {
|
func TestInt64(t *testing.T) {
|
||||||
for i, testVal := range int64Tests {
|
for _, s := range int64Tests {
|
||||||
in := NewInt(testVal)
|
var x Int
|
||||||
out := in.Int64()
|
_, ok := x.SetString(s, 0)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("SetString(%s, 0) failed", s)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if out != testVal {
|
want, err := strconv.ParseInt(s, 0, 64)
|
||||||
t.Errorf("#%d got %d want %d", i, out, testVal)
|
if err != nil {
|
||||||
|
if err.(*strconv.NumError).Err == strconv.ErrRange {
|
||||||
|
if x.IsInt64() {
|
||||||
|
t.Errorf("IsInt64(%s) succeeded unexpectedly", s)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("ParseInt(%s) failed", s)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !x.IsInt64() {
|
||||||
|
t.Errorf("IsInt64(%s) failed unexpectedly", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
got := x.Int64()
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("Int64(%s) = %d; want %d", s, got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var uint64Tests = []uint64{
|
var uint64Tests = []string{
|
||||||
0,
|
// uint64
|
||||||
1,
|
"0",
|
||||||
4294967295,
|
"1",
|
||||||
4294967296,
|
"4294967295",
|
||||||
8589934591,
|
"4294967296",
|
||||||
8589934592,
|
"8589934591",
|
||||||
9223372036854775807,
|
"8589934592",
|
||||||
9223372036854775808,
|
"9223372036854775807",
|
||||||
18446744073709551615, // 1<<64 - 1
|
"9223372036854775808",
|
||||||
|
"0x08000000000000000",
|
||||||
|
|
||||||
|
// not uint64
|
||||||
|
"0x10000000000000000",
|
||||||
|
"-0x08000000000000000",
|
||||||
|
"-1",
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUint64(t *testing.T) {
|
func TestUint64(t *testing.T) {
|
||||||
in := new(Int)
|
for _, s := range uint64Tests {
|
||||||
for i, testVal := range uint64Tests {
|
var x Int
|
||||||
in.SetUint64(testVal)
|
_, ok := x.SetString(s, 0)
|
||||||
out := in.Uint64()
|
if !ok {
|
||||||
|
t.Errorf("SetString(%s, 0) failed", s)
|
||||||
if out != testVal {
|
continue
|
||||||
t.Errorf("#%d got %d want %d", i, out, testVal)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
str := fmt.Sprint(testVal)
|
want, err := strconv.ParseUint(s, 0, 64)
|
||||||
strOut := in.String()
|
if err != nil {
|
||||||
if strOut != str {
|
// check for sign explicitly (ErrRange doesn't cover signed input)
|
||||||
t.Errorf("#%d.String got %s want %s", i, strOut, str)
|
if s[0] == '-' || err.(*strconv.NumError).Err == strconv.ErrRange {
|
||||||
|
if x.IsUint64() {
|
||||||
|
t.Errorf("IsUint64(%s) succeeded unexpectedly", s)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Errorf("ParseUint(%s) failed", s)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !x.IsUint64() {
|
||||||
|
t.Errorf("IsUint64(%s) failed unexpectedly", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
got := x.Uint64()
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("Uint64(%s) = %d; want %d", s, got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user