feat: collection 包新增 Equel 命名前缀的用于比较切片和 map 元素是否相同的函数,新增 Loop 命名前缀的用于遍历切片和 map 元素的函数

This commit is contained in:
kercylan98 2024-01-19 14:46:24 +08:00
parent c4605cc4c3
commit 756f823ca4
9 changed files with 1421 additions and 6 deletions

View File

@ -1,5 +1,61 @@
package collection
// EqualSlice 检查两个切片是否相等,当 handler 返回 true 时,表示 slice1 中的某个元素和 slice2 中的某个元素相匹配
// - 当两个切片的容量不同时,不会影响最终的比较结果
func EqualSlice[S ~[]V, V any](slice1 S, slice2 S, handler ComparisonHandler[V]) bool {
if len(slice1) != len(slice2) {
return false
}
for i, v1 := range slice1 {
if !handler(v1, slice2[i]) {
return false
}
}
return true
}
// EqualComparableSlice 检查两个切片的值是否相同
// - 当两个切片的容量不同时,不会影响最终的比较结果
func EqualComparableSlice[S ~[]V, V comparable](slice1 S, slice2 S) bool {
if len(slice1) != len(slice2) {
return false
}
for i, v1 := range slice1 {
if v1 != slice2[i] {
return false
}
}
return true
}
// EqualMap 检查两个 map 是否相等,当 handler 返回 true 时,表示 map1 中的某个元素和 map2 中的某个元素相匹配
// - 当两个 map 的容量不同时,不会影响最终的比较结果
func EqualMap[M ~map[K]V, K comparable, V any](map1 M, map2 M, handler ComparisonHandler[V]) bool {
if len(map1) != len(map2) {
return false
}
for k, v1 := range map1 {
if !handler(v1, map2[k]) {
return false
}
}
return true
}
// EqualComparableMap 检查两个 map 的值是否相同
// - 当两个 map 的容量不同时,不会影响最终的比较结果
func EqualComparableMap[M ~map[K]V, K comparable, V comparable](map1 M, map2 M) bool {
if len(map1) != len(map2) {
return false
}
for k, v1 := range map1 {
if v1 != map2[k] {
return false
}
}
return true
}
// InSlice 检查 v 是否被包含在 slice 中,当 handler 返回 true 时,表示 v 和 slice 中的某个元素相匹配
func InSlice[S ~[]V, V any](slice S, v V, handler ComparisonHandler[V]) bool {
if len(slice) == 0 {

View File

@ -5,6 +5,58 @@ import (
"github.com/kercylan98/minotaur/utils/collection"
)
func ExampleEqualSlice() {
s1 := []int{1, 2, 3}
s2 := []int{1}
s3 := []int{1, 2, 3}
fmt.Println(collection.EqualSlice(s1, s2, func(source, target int) bool {
return source == target
}))
fmt.Println(collection.EqualSlice(s1, s3, func(source, target int) bool {
return source == target
}))
// Output:
// false
// true
}
func ExampleEqualComparableSlice() {
s1 := []int{1, 2, 3}
s2 := []int{1}
s3 := []int{1, 2, 3}
fmt.Println(collection.EqualComparableSlice(s1, s2))
fmt.Println(collection.EqualComparableSlice(s1, s3))
// Output:
// false
// true
}
func ExampleEqualMap() {
m1 := map[string]int{"a": 1, "b": 2}
m2 := map[string]int{"a": 1}
m3 := map[string]int{"a": 1, "b": 2}
fmt.Println(collection.EqualMap(m1, m2, func(source, target int) bool {
return source == target
}))
fmt.Println(collection.EqualMap(m1, m3, func(source, target int) bool {
return source == target
}))
// Output:
// false
// true
}
func ExampleEqualComparableMap() {
m1 := map[string]int{"a": 1, "b": 2}
m2 := map[string]int{"a": 1}
m3 := map[string]int{"a": 1, "b": 2}
fmt.Println(collection.EqualComparableMap(m1, m2))
fmt.Println(collection.EqualComparableMap(m1, m3))
// Output:
// false
// true
}
func ExampleInSlice() {
result := collection.InSlice([]int{1, 2, 3}, 2, func(source, target int) bool {
return source == target

View File

@ -9,6 +9,106 @@ var intComparisonHandler = func(source, target int) bool {
return source == target
}
func TestEqualSlice(t *testing.T) {
var cases = []struct {
name string
input []int
inputV []int
expected bool
}{
{"TestEqualSlice_NonEmptySliceEqual", []int{1, 2, 3}, []int{1, 2, 3}, true},
{"TestEqualSlice_NonEmptySliceNotEqual", []int{1, 2, 3}, []int{1, 2}, false},
{"TestEqualSlice_EmptySlice", []int{}, []int{}, true},
{"TestEqualSlice_NilSlice", nil, nil, true},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var actual = collection.EqualSlice(c.input, c.inputV, func(source, target int) bool {
return source == target
})
if actual != c.expected {
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s",
c.name, c.expected, actual, "not as expected")
}
})
}
}
func TestEqualComparableSlice(t *testing.T) {
var cases = []struct {
name string
input []int
inputV []int
expected bool
}{
{"TestEqualComparableSlice_NonEmptySliceEqual", []int{1, 2, 3}, []int{1, 2, 3}, true},
{"TestEqualComparableSlice_NonEmptySliceNotEqual", []int{1, 2, 3}, []int{1, 2}, false},
{"TestEqualComparableSlice_EmptySlice", []int{}, []int{}, true},
{"TestEqualComparableSlice_NilSlice", nil, nil, true},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var actual = collection.EqualComparableSlice(c.input, c.inputV)
if actual != c.expected {
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s",
c.name, c.expected, actual, "not as expected")
}
})
}
}
func TestEqualMap(t *testing.T) {
var cases = []struct {
name string
input map[int]int
inputV map[int]int
expected bool
}{
{"TestEqualMap_NonEmptyMapEqual", map[int]int{1: 1, 2: 2}, map[int]int{1: 1, 2: 2}, true},
{"TestEqualMap_NonEmptyMapNotEqual", map[int]int{1: 1, 2: 2}, map[int]int{1: 1}, false},
{"TestEqualMap_EmptyMap", map[int]int{}, map[int]int{}, true},
{"TestEqualMap_NilMap", nil, nil, true},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var actual = collection.EqualMap(c.input, c.inputV, func(source, target int) bool {
return source == target
})
if actual != c.expected {
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s",
c.name, c.expected, actual, "not as expected")
}
})
}
}
func TestEqualComparableMap(t *testing.T) {
var cases = []struct {
name string
input map[int]int
inputV map[int]int
expected bool
}{
{"TestEqualComparableMap_NonEmptyMapEqual", map[int]int{1: 1, 2: 2}, map[int]int{1: 1, 2: 2}, true},
{"TestEqualComparableMap_NonEmptyMapNotEqual", map[int]int{1: 1, 2: 2}, map[int]int{1: 1}, false},
{"TestEqualComparableMap_EmptyMap", map[int]int{}, map[int]int{}, true},
{"TestEqualComparableMap_NilMap", nil, nil, true},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var actual = collection.EqualComparableMap(c.input, c.inputV)
if actual != c.expected {
t.Fatalf("%s failed, expected: %v, actual: %v, error: %s",
c.name, c.expected, actual, "not as expected")
}
})
}
}
func TestInSlice(t *testing.T) {
var cases = []struct {
name string

188
utils/collection/loop.go Normal file
View File

@ -0,0 +1,188 @@
package collection
import (
"github.com/kercylan98/minotaur/utils/generic"
"sort"
)
// LoopSlice 迭代切片 slice 中的每一个函数,并将索引和值传递给 f 函数
// - 迭代过程将在 f 函数返回 false 时中断
func LoopSlice[S ~[]V, V any](slice S, f func(i int, val V) bool) {
for i, v := range slice {
if !f(i, v) {
break
}
}
}
// ReverseLoopSlice 逆序迭代切片 slice 中的每一个函数,并将索引和值传递给 f 函数
// - 迭代过程将在 f 函数返回 false 时中断
func ReverseLoopSlice[S ~[]V, V any](slice S, f func(i int, val V) bool) {
for i := len(slice) - 1; i >= 0; i-- {
if !f(i, slice[i]) {
break
}
}
}
// LoopMap 迭代 m 中的每一个函数,并将键和值传递给 f 函数
// - m 的迭代顺序是不确定的,因此每次迭代的顺序可能不同
// - 该函数会在 f 中传入一个从 0 开始的索引,用于表示当前迭代的次数
// - 迭代过程将在 f 函数返回 false 时中断
func LoopMap[M ~map[K]V, K comparable, V any](m M, f func(i int, key K, val V) bool) {
var i int
for k, v := range m {
if !f(i, k, v) {
break
}
i++
}
}
// LoopMapByOrderedKeyAsc 按照键的升序迭代 m 中的每一个函数,并将键和值传递给 f 函数
// - 该函数会在 f 中传入一个从 0 开始的索引,用于表示当前迭代的次数
// - 迭代过程将在 f 函数返回 false 时中断
func LoopMapByOrderedKeyAsc[M ~map[K]V, K generic.Ordered, V any](m M, f func(i int, key K, val V) bool) {
var keys []K
for k := range m {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
return AscBy(keys[i], keys[j])
})
for i, k := range keys {
if !f(i, k, m[k]) {
break
}
}
}
// LoopMapByOrderedKeyDesc 按照键的降序迭代 m 中的每一个函数,并将键和值传递给 f 函数
// - 该函数会在 f 中传入一个从 0 开始的索引,用于表示当前迭代的次数
// - 迭代过程将在 f 函数返回 false 时中断
func LoopMapByOrderedKeyDesc[M ~map[K]V, K generic.Ordered, V any](m M, f func(i int, key K, val V) bool) {
var keys []K
for k := range m {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
return DescBy(keys[i], keys[j])
})
for i, k := range keys {
if !f(i, k, m[k]) {
break
}
}
}
// LoopMapByOrderedValueAsc 按照值的升序迭代 m 中的每一个函数,并将键和值传递给 f 函数
// - 该函数会在 f 中传入一个从 0 开始的索引,用于表示当前迭代的次数
// - 迭代过程将在 f 函数返回 false 时中断
func LoopMapByOrderedValueAsc[M ~map[K]V, K comparable, V generic.Ordered](m M, f func(i int, key K, val V) bool) {
var keys []K
var values []V
for k, v := range m {
keys = append(keys, k)
values = append(values, v)
}
sort.Slice(values, func(i, j int) bool {
return AscBy(values[i], values[j])
})
for i, v := range values {
if !f(i, keys[i], v) {
break
}
}
}
// LoopMapByOrderedValueDesc 按照值的降序迭代 m 中的每一个函数,并将键和值传递给 f 函数
// - 该函数会在 f 中传入一个从 0 开始的索引,用于表示当前迭代的次数
// - 迭代过程将在 f 函数返回 false 时中断
func LoopMapByOrderedValueDesc[M ~map[K]V, K comparable, V generic.Ordered](m M, f func(i int, key K, val V) bool) {
var keys []K
var values []V
for k, v := range m {
keys = append(keys, k)
values = append(values, v)
}
sort.Slice(values, func(i, j int) bool {
return DescBy(values[i], values[j])
})
for i, v := range values {
if !f(i, keys[i], v) {
break
}
}
}
// LoopMapByKeyGetterAsc 按照键的升序迭代 m 中的每一个函数,并将键和值传递给 f 函数
// - 该函数会在 f 中传入一个从 0 开始的索引,用于表示当前迭代的次数
// - 迭代过程将在 f 函数返回 false 时中断
func LoopMapByKeyGetterAsc[M ~map[K]V, K comparable, V comparable, N generic.Ordered](m M, getter func(k K) N, f func(i int, key K, val V) bool) {
var keys []K
for k := range m {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
return AscBy(getter(keys[i]), getter(keys[j]))
})
for i, v := range keys {
if !f(i, keys[i], m[v]) {
break
}
}
}
// LoopMapByValueGetterAsc 按照值的升序迭代 m 中的每一个函数,并将键和值传递给 f 函数
// - 该函数会在 f 中传入一个从 0 开始的索引,用于表示当前迭代的次数
// - 迭代过程将在 f 函数返回 false 时中断
func LoopMapByValueGetterAsc[M ~map[K]V, K comparable, V any, N generic.Ordered](m M, getter func(v V) N, f func(i int, key K, val V) bool) {
var keys []K
for k := range m {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
return AscBy(getter(m[keys[i]]), getter(m[keys[j]]))
})
for i, v := range keys {
if !f(i, keys[i], m[v]) {
break
}
}
}
// LoopMapByKeyGetterDesc 按照键的降序迭代 m 中的每一个函数,并将键和值传递给 f 函数
// - 该函数会在 f 中传入一个从 0 开始的索引,用于表示当前迭代的次数
// - 迭代过程将在 f 函数返回 false 时中断
func LoopMapByKeyGetterDesc[M ~map[K]V, K comparable, V comparable, N generic.Ordered](m M, getter func(k K) N, f func(i int, key K, val V) bool) {
var keys []K
for k := range m {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
return DescBy(getter(keys[i]), getter(keys[j]))
})
for i, v := range keys {
if !f(i, keys[i], m[v]) {
break
}
}
}
// LoopMapByValueGetterDesc 按照值的降序迭代 m 中的每一个函数,并将键和值传递给 f 函数
// - 该函数会在 f 中传入一个从 0 开始的索引,用于表示当前迭代的次数
// - 迭代过程将在 f 函数返回 false 时中断
func LoopMapByValueGetterDesc[M ~map[K]V, K comparable, V any, N generic.Ordered](m M, getter func(v V) N, f func(i int, key K, val V) bool) {
var keys []K
for k := range m {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
return DescBy(getter(m[keys[i]]), getter(m[keys[j]]))
})
for i, v := range keys {
if !f(i, keys[i], m[v]) {
break
}
}
}

View File

@ -0,0 +1,159 @@
package collection_test
import (
"fmt"
"github.com/kercylan98/minotaur/utils/collection"
)
func ExampleLoopSlice() {
var result []int
collection.LoopSlice([]int{1, 2, 3, 4, 5}, func(i int, val int) bool {
result = append(result, val)
if uint(i) == 1 {
return false
}
return true
})
fmt.Println(result)
// Output: [1 2]
}
func ExampleReverseLoopSlice() {
var result []int
collection.ReverseLoopSlice([]int{1, 2, 3, 4, 5}, func(i int, val int) bool {
result = append(result, val)
if uint(i) == 1 {
return false
}
return true
})
fmt.Println(result)
// Output: [5 4 3 2]
}
func ExampleLoopMap() {
var result []int
collection.LoopMap(map[string]int{"a": 1, "b": 2, "c": 3}, func(i int, key string, val int) bool {
result = append(result, val)
return true
})
fmt.Println(collection.AllInComparableSlice(result, []int{1, 2, 3}))
// Output:
// true
}
func ExampleLoopMapByOrderedKeyAsc() {
var result []int
collection.LoopMapByOrderedKeyAsc(map[string]int{"a": 1, "b": 2, "c": 3}, func(i int, key string, val int) bool {
result = append(result, val)
return true
})
fmt.Println(collection.AllInComparableSlice(result, []int{1, 2, 3}))
// Output:
// true
}
func ExampleLoopMapByOrderedKeyDesc() {
var result []int
collection.LoopMapByOrderedKeyDesc(map[string]int{"a": 1, "b": 2, "c": 3}, func(i int, key string, val int) bool {
result = append(result, val)
return true
})
fmt.Println(collection.AllInComparableSlice(result, []int{3, 2, 1}))
// Output:
// true
}
func ExampleLoopMapByOrderedValueAsc() {
var result []int
collection.LoopMapByOrderedValueAsc(map[string]int{"a": 1, "b": 2, "c": 3}, func(i int, key string, val int) bool {
result = append(result, val)
return true
})
fmt.Println(collection.AllInComparableSlice(result, []int{1, 2, 3}))
// Output:
// true
}
func ExampleLoopMapByOrderedValueDesc() {
var result []int
collection.LoopMapByOrderedValueDesc(map[string]int{"a": 1, "b": 2, "c": 3}, func(i int, key string, val int) bool {
result = append(result, val)
return true
})
fmt.Println(collection.AllInComparableSlice(result, []int{3, 2, 1}))
// Output:
// true
}
func ExampleLoopMapByKeyGetterAsc() {
var m = map[string]int{"a": 1, "b": 2, "c": 3}
var result []int
collection.LoopMapByKeyGetterAsc(
m,
func(k string) int {
return m[k]
},
func(i int, key string, val int) bool {
result = append(result, val)
return true
},
)
fmt.Println(collection.AllInComparableSlice(result, []int{1, 2, 3}))
// Output:
// true
}
func ExampleLoopMapByKeyGetterDesc() {
var m = map[string]int{"a": 1, "b": 2, "c": 3}
var result []int
collection.LoopMapByKeyGetterDesc(
m,
func(k string) int {
return m[k]
},
func(i int, key string, val int) bool {
result = append(result, val)
return true
},
)
fmt.Println(collection.AllInComparableSlice(result, []int{3, 2, 1}))
// Output:
// true
}
func ExampleLoopMapByValueGetterAsc() {
var m = map[string]int{"a": 1, "b": 2, "c": 3}
var result []int
collection.LoopMapByValueGetterAsc(
m,
func(v int) int {
return v
},
func(i int, key string, val int) bool {
result = append(result, val)
return true
},
)
fmt.Println(collection.AllInComparableSlice(result, []int{1, 2, 3}))
// Output:
// true
}
func ExampleLoopMapByValueGetterDesc() {
var m = map[string]int{"a": 1, "b": 2, "c": 3}
var result []int
collection.LoopMapByValueGetterDesc(
m,
func(v int) int {
return v
},
func(i int, key string, val int) bool {
result = append(result, val)
return true
},
)
fmt.Println(collection.AllInComparableSlice(result, []int{3, 2, 1}))
// Output:
// true
}

View File

@ -0,0 +1,333 @@
package collection_test
import (
"github.com/kercylan98/minotaur/utils/collection"
"testing"
)
func TestLoopSlice(t *testing.T) {
var cases = []struct {
name string
in []int
out []int
breakIndex uint
}{
{"TestLoopSlice_Part", []int{1, 2, 3, 4, 5}, []int{1, 2}, 2},
{"TestLoopSlice_All", []int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4, 5}, 0},
{"TestLoopSlice_Empty", []int{}, []int{}, 0},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var result []int
collection.LoopSlice(c.in, func(i int, val int) bool {
result = append(result, val)
if c.breakIndex != 0 && uint(i) == c.breakIndex-1 {
return false
}
return true
})
if !collection.EqualComparableSlice(result, c.out) {
t.Errorf("LoopSlice(%v) got %v, want %v", c.in, result, c.out)
}
})
}
}
func TestReverseLoopSlice(t *testing.T) {
var cases = []struct {
name string
in []int
out []int
breakIndex uint
}{
{"TestReverseLoopSlice_Part", []int{1, 2, 3, 4, 5}, []int{5, 4}, 2},
{"TestReverseLoopSlice_All", []int{1, 2, 3, 4, 5}, []int{5, 4, 3, 2, 1}, 0},
{"TestReverseLoopSlice_Empty", []int{}, []int{}, 0},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var result []int
collection.ReverseLoopSlice(c.in, func(i int, val int) bool {
result = append(result, val)
if c.breakIndex != 0 && uint(i) == uint(len(c.in))-c.breakIndex {
return false
}
return true
})
if !collection.EqualComparableSlice(result, c.out) {
t.Errorf("ReverseLoopSlice(%v) got %v, want %v", c.in, result, c.out)
}
})
}
}
func TestLoopMap(t *testing.T) {
var cases = []struct {
name string
in map[int]string
out map[int]string
breakIndex uint
}{
{"TestLoopMap_Part", map[int]string{1: "1", 2: "2", 3: "3"}, map[int]string{1: "1", 2: "2"}, 2},
{"TestLoopMap_All", map[int]string{1: "1", 2: "2", 3: "3"}, map[int]string{1: "1", 2: "2", 3: "3"}, 0},
{"TestLoopMap_Empty", map[int]string{}, map[int]string{}, 0},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var result = make(map[int]string)
collection.LoopMap(c.in, func(i int, key int, val string) bool {
result[key] = val
if c.breakIndex != 0 && uint(i) == c.breakIndex-1 {
return false
}
return true
})
if !collection.EqualComparableMap(result, c.out) {
t.Errorf("LoopMap(%v) got %v, want %v", c.in, result, c.out)
}
})
}
}
func TestLoopMapByOrderedKeyAsc(t *testing.T) {
var cases = []struct {
name string
in map[int]string
out []int
breakIndex uint
}{
{"TestLoopMapByOrderedKeyAsc_Part", map[int]string{1: "1", 2: "2", 3: "3"}, []int{1, 2}, 2},
{"TestLoopMapByOrderedKeyAsc_All", map[int]string{1: "1", 2: "2", 3: "3"}, []int{1, 2, 3}, 0},
{"TestLoopMapByOrderedKeyAsc_Empty", map[int]string{}, []int{}, 0},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var result []int
collection.LoopMapByOrderedKeyAsc(c.in, func(i int, key int, val string) bool {
result = append(result, key)
if c.breakIndex != 0 && uint(i) == c.breakIndex-1 {
return false
}
return true
})
if !collection.EqualComparableSlice(result, c.out) {
t.Errorf("LoopMapByOrderedKeyAsc(%v) got %v, want %v", c.in, result, c.out)
}
})
}
}
func TestLoopMapByOrderedKeyDesc(t *testing.T) {
var cases = []struct {
name string
in map[int]string
out []int
breakIndex uint
}{
{"TestLoopMapByOrderedKeyDesc_Part", map[int]string{1: "1", 2: "2", 3: "3"}, []int{3, 2}, 2},
{"TestLoopMapByOrderedKeyDesc_All", map[int]string{1: "1", 2: "2", 3: "3"}, []int{3, 2, 1}, 0},
{"TestLoopMapByOrderedKeyDesc_Empty", map[int]string{}, []int{}, 0},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var result []int
collection.LoopMapByOrderedKeyDesc(c.in, func(i int, key int, val string) bool {
result = append(result, key)
if c.breakIndex != 0 && uint(i) == c.breakIndex-1 {
return false
}
return true
})
if !collection.EqualComparableSlice(result, c.out) {
t.Errorf("LoopMapByOrderedKeyDesc(%v) got %v, want %v", c.in, result, c.out)
}
})
}
}
func TestLoopMapByOrderedValueAsc(t *testing.T) {
var cases = []struct {
name string
in map[int]string
out []string
breakIndex uint
}{
{"TestLoopMapByOrderedValueAsc_Part", map[int]string{1: "1", 2: "2", 3: "3"}, []string{"1", "2"}, 2},
{"TestLoopMapByOrderedValueAsc_All", map[int]string{1: "1", 2: "2", 3: "3"}, []string{"1", "2", "3"}, 0},
{"TestLoopMapByOrderedValueAsc_Empty", map[int]string{}, []string{}, 0},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var result []string
collection.LoopMapByOrderedValueAsc(c.in, func(i int, key int, val string) bool {
result = append(result, val)
if c.breakIndex != 0 && uint(i) == c.breakIndex-1 {
return false
}
return true
})
if !collection.EqualComparableSlice(result, c.out) {
t.Errorf("LoopMapByOrderedValueAsc(%v) got %v, want %v", c.in, result, c.out)
}
})
}
}
func TestLoopMapByOrderedValueDesc(t *testing.T) {
var cases = []struct {
name string
in map[int]string
out []string
breakIndex uint
}{
{"TestLoopMapByOrderedValueDesc_Part", map[int]string{1: "1", 2: "2", 3: "3"}, []string{"3", "2"}, 2},
{"TestLoopMapByOrderedValueDesc_All", map[int]string{1: "1", 2: "2", 3: "3"}, []string{"3", "2", "1"}, 0},
{"TestLoopMapByOrderedValueDesc_Empty", map[int]string{}, []string{}, 0},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var result []string
collection.LoopMapByOrderedValueDesc(c.in, func(i int, key int, val string) bool {
result = append(result, val)
if c.breakIndex != 0 && uint(i) == c.breakIndex-1 {
return false
}
return true
})
if !collection.EqualComparableSlice(result, c.out) {
t.Errorf("LoopMapByOrderedValueDesc(%v) got %v, want %v", c.in, result, c.out)
}
})
}
}
func TestLoopMapByKeyGetterAsc(t *testing.T) {
var cases = []struct {
name string
in map[int]string
out []int
breakIndex uint
}{
{"TestLoopMapByKeyGetterAsc_Part", map[int]string{1: "1", 2: "2", 3: "3"}, []int{1, 2}, 2},
{"TestLoopMapByKeyGetterAsc_All", map[int]string{1: "1", 2: "2", 3: "3"}, []int{1, 2, 3}, 0},
{"TestLoopMapByKeyGetterAsc_Empty", map[int]string{}, []int{}, 0},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var result []int
collection.LoopMapByKeyGetterAsc(c.in, func(key int) int {
return key
}, func(i int, key int, val string) bool {
result = append(result, key)
if c.breakIndex != 0 && uint(i) == c.breakIndex-1 {
return false
}
return true
})
if !collection.EqualComparableSlice(result, c.out) {
t.Errorf("LoopMapByKeyGetterAsc(%v) got %v, want %v", c.in, result, c.out)
}
})
}
}
func TestLoopMapByKeyGetterDesc(t *testing.T) {
var cases = []struct {
name string
in map[int]string
out []int
breakIndex uint
}{
{"TestLoopMapByKeyGetterDesc_Part", map[int]string{1: "1", 2: "2", 3: "3"}, []int{3, 2}, 2},
{"TestLoopMapByKeyGetterDesc_All", map[int]string{1: "1", 2: "2", 3: "3"}, []int{3, 2, 1}, 0},
{"TestLoopMapByKeyGetterDesc_Empty", map[int]string{}, []int{}, 0},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var result []int
collection.LoopMapByKeyGetterDesc(c.in, func(key int) int {
return key
}, func(i int, key int, val string) bool {
result = append(result, key)
if c.breakIndex != 0 && uint(i) == c.breakIndex-1 {
return false
}
return true
})
if !collection.EqualComparableSlice(result, c.out) {
t.Errorf("LoopMapByKeyGetterDesc(%v) got %v, want %v", c.in, result, c.out)
}
})
}
}
func TestLoopMapByValueGetterAsc(t *testing.T) {
var cases = []struct {
name string
in map[int]string
out []string
breakIndex uint
}{
{"TestLoopMapByValueGetterAsc_Part", map[int]string{1: "1", 2: "2", 3: "3"}, []string{"1", "2"}, 2},
{"TestLoopMapByValueGetterAsc_All", map[int]string{1: "1", 2: "2", 3: "3"}, []string{"1", "2", "3"}, 0},
{"TestLoopMapByValueGetterAsc_Empty", map[int]string{}, []string{}, 0},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var result []string
collection.LoopMapByValueGetterAsc(c.in, func(val string) string {
return val
}, func(i int, key int, val string) bool {
result = append(result, val)
if c.breakIndex != 0 && uint(i) == c.breakIndex-1 {
return false
}
return true
})
if !collection.EqualComparableSlice(result, c.out) {
t.Errorf("LoopMapByValueGetterAsc(%v) got %v, want %v", c.in, result, c.out)
}
})
}
}
func TestLoopMapByValueGetterDesc(t *testing.T) {
var cases = []struct {
name string
in map[int]string
out []string
breakIndex uint
}{
{"TestLoopMapByValueGetterDesc_Part", map[int]string{1: "1", 2: "2", 3: "3"}, []string{"3", "2"}, 2},
{"TestLoopMapByValueGetterDesc_All", map[int]string{1: "1", 2: "2", 3: "3"}, []string{"3", "2", "1"}, 0},
{"TestLoopMapByValueGetterDesc_Empty", map[int]string{}, []string{}, 0},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var result []string
collection.LoopMapByValueGetterDesc(c.in, func(val string) string {
return val
}, func(i int, key int, val string) bool {
result = append(result, val)
if c.breakIndex != 0 && uint(i) == c.breakIndex-1 {
return false
}
return true
})
if !collection.EqualComparableSlice(result, c.out) {
t.Errorf("LoopMapByValueGetterDesc(%v) got %v, want %v", c.in, result, c.out)
}
})
}
}

View File

@ -85,42 +85,67 @@ func (slf *Int) SetInt(i int) *Int {
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
}
// SetInt8 设置当前 Int 对象的值为 i
func (slf *Int) SetInt8(i int8) *Int {
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
}
// SetInt16 设置当前 Int 对象的值为 i
func (slf *Int) SetInt16(i int16) *Int {
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
}
// SetInt32 设置当前 Int 对象的值为 i
func (slf *Int) SetInt32(i int32) *Int {
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
}
// SetInt64 设置当前 Int 对象的值为 i
func (slf *Int) SetInt64(i int64) *Int {
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
}
// SetUint 设置当前 Int 对象的值为 i
func (slf *Int) SetUint(i uint) *Int {
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
}
// SetUint8 设置当前 Int 对象的值为 i
func (slf *Int) SetUint8(i uint8) *Int {
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
}
// SetUint16 设置当前 Int 对象的值为 i
func (slf *Int) SetUint16(i uint16) *Int {
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
}
// SetUint32 设置当前 Int 对象的值为 i
func (slf *Int) SetUint32(i uint32) *Int {
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
}
// SetUint64 设置当前 Int 对象的值为 i
func (slf *Int) SetUint64(i uint64) *Int {
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
}
// SetFloat32 设置当前 Int 对象的值为 i 向下取整后的值
func (slf *Int) SetFloat32(i float32) *Int {
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
}
// SetFloat64 设置当前 Int 对象的值为 i 向下取整后的值
func (slf *Int) SetFloat64(i float64) *Int {
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
}
// SetBool 设置当前 Int 对象的值为 i当 i 为 true 时,值为 1当 i 为 false 时,值为 0
func (slf *Int) SetBool(i bool) *Int {
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
}
// IsZero 判断当前 Int 对象的值是否为 0
func (slf *Int) IsZero() bool {
if slf == nil || slf.EqualTo(IntZero) {
return true
@ -128,6 +153,7 @@ func (slf *Int) IsZero() bool {
return false
}
// ToBigint 转换为 *big.Int
func (slf *Int) ToBigint() *big.Int {
if slf == nil {
return big.NewInt(0)
@ -140,35 +166,37 @@ func (slf *Int) Cmp(i *Int) int {
return slf.ToBigint().Cmp(i.ToBigint())
}
// GreaterThan 大于
// GreaterThan 检查 slf 是否大于 i
func (slf *Int) GreaterThan(i *Int) bool {
return slf.Cmp(i) > 0
}
// GreaterThanOrEqualTo 大于或等于
// GreaterThanOrEqualTo 检查 slf 是否大于或等于 i
func (slf *Int) GreaterThanOrEqualTo(i *Int) bool {
return slf.Cmp(i) >= 0
}
// LessThan 小于
// LessThan 检查 slf 是否小于 i
func (slf *Int) LessThan(i *Int) bool {
return slf.Cmp(i) < 0
}
// LessThanOrEqualTo 小于或等于
// LessThanOrEqualTo 检查 slf 是否小于或等于 i
func (slf *Int) LessThanOrEqualTo(i *Int) bool {
return slf.Cmp(i) <= 0
}
// EqualTo 等于
// EqualTo 检查 slf 是否等于 i
func (slf *Int) EqualTo(i *Int) bool {
return slf.Cmp(i) == 0
}
// Int64 转换为 int64 类型进行返回
func (slf *Int) Int64() int64 {
return slf.ToBigint().Int64()
}
// String 转换为 string 类型进行返回
func (slf *Int) String() string {
if slf == nil {
return "0"
@ -176,6 +204,7 @@ func (slf *Int) String() string {
return slf.ToBigint().String()
}
// Add 使用 i 对 slf 进行加法运算slf 的值会变为运算后的值。返回 slf
func (slf *Int) Add(i *Int) *Int {
x := slf.ToBigint()
return (*Int)(x.Add(x, i.ToBigint()))

View File

@ -0,0 +1,42 @@
package huge_test
import (
"fmt"
"github.com/kercylan98/minotaur/utils/huge"
)
// 该案例展示了 NewInt 对各种基本类型的支持及用法
func ExampleNewInt() {
fmt.Println(huge.NewInt("12345678900000000"))
fmt.Println(huge.NewInt(1234567890))
fmt.Println(huge.NewInt(true))
fmt.Println(huge.NewInt(123.123))
fmt.Println(huge.NewInt(byte(1)))
// Output:
// 12345678900000000
// 1234567890
// 1
// 123
// 1
}
func ExampleInt_Copy() {
var a = huge.NewInt(1234567890)
var b = a.Copy().SetInt64(9876543210)
fmt.Println(a)
fmt.Println(b)
// Output:
// 1234567890
// 9876543210
}
func ExampleInt_Set() {
var a = huge.NewInt(1234567890)
var b = huge.NewInt(9876543210)
fmt.Println(a)
a.Set(b)
fmt.Println(a)
// Output:
// 1234567890
// 9876543210
}

View File

@ -2,6 +2,7 @@ package huge_test
import (
"github.com/kercylan98/minotaur/utils/huge"
"math/big"
"testing"
)
@ -38,7 +39,7 @@ func TestNewInt(t *testing.T) {
got = huge.NewInt(c.in).MulInt64(c.mul)
}
if s := got.String(); s != c.want {
t.Errorf("want: %s, got: %s", c.want, got.String())
t.Fatalf("want: %s, got: %s", c.want, got.String())
} else {
t.Log(s)
}
@ -67,3 +68,458 @@ func TestNewInt(t *testing.T) {
}
})
}
func TestInt_Copy(t *testing.T) {
var cases = []struct {
name string
in int64
want string
}{
{name: "TestIntCopyNegative", in: -1, want: "-1"},
{name: "TestIntCopyZero", in: 0, want: "0"},
{name: "TestIntCopyPositive", in: 1, want: "1"},
{name: "TestIntCopyMax", in: 9223372036854775807, want: "9223372036854775807"},
{name: "TestIntCopyMin", in: -9223372036854775808, want: "-9223372036854775808"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in = huge.NewInt(c.in)
var got = in.Copy()
if in.Int64() != c.in {
t.Fatalf("want: %d, got: %d", c.in, in.Int64())
}
if s := got.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, got.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_Set(t *testing.T) {
var cases = []struct {
name string
in int64
want string
}{
{name: "TestIntSetNegative", in: -1, want: "-1"},
{name: "TestIntSetZero", in: 0, want: "0"},
{name: "TestIntSetPositive", in: 1, want: "1"},
{name: "TestIntSetMax", in: 9223372036854775807, want: "9223372036854775807"},
{name: "TestIntSetMin", in: -9223372036854775808, want: "-9223372036854775808"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.Set(huge.NewInt(c.in))
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_SetString(t *testing.T) {
var cases = []struct {
name string
in string
want string
}{
{name: "TestIntSetStringNegative", in: "-1", want: "-1"},
{name: "TestIntSetStringZero", in: "0", want: "0"},
{name: "TestIntSetStringPositive", in: "1", want: "1"},
{name: "TestIntSetStringMax", in: "9223372036854775807", want: "9223372036854775807"},
{name: "TestIntSetStringMin", in: "-9223372036854775808", want: "-9223372036854775808"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetString(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_SetInt(t *testing.T) {
var cases = []struct {
name string
in int64
want string
}{
{name: "TestIntSetIntNegative", in: -1, want: "-1"},
{name: "TestIntSetIntZero", in: 0, want: "0"},
{name: "TestIntSetIntPositive", in: 1, want: "1"},
{name: "TestIntSetIntMax", in: 9223372036854775807, want: "9223372036854775807"},
{name: "TestIntSetIntMin", in: -9223372036854775808, want: "-9223372036854775808"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetInt64(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_SetInt8(t *testing.T) {
var cases = []struct {
name string
in int8
want string
}{
{name: "TestIntSetInt8Negative", in: -1, want: "-1"},
{name: "TestIntSetInt8Zero", in: 0, want: "0"},
{name: "TestIntSetInt8Positive", in: 1, want: "1"},
{name: "TestIntSetInt8Max", in: 127, want: "127"},
{name: "TestIntSetInt8Min", in: -128, want: "-128"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetInt8(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_SetInt16(t *testing.T) {
var cases = []struct {
name string
in int16
want string
}{
{name: "TestIntSetInt16Negative", in: -1, want: "-1"},
{name: "TestIntSetInt16Zero", in: 0, want: "0"},
{name: "TestIntSetInt16Positive", in: 1, want: "1"},
{name: "TestIntSetInt16Max", in: 32767, want: "32767"},
{name: "TestIntSetInt16Min", in: -32768, want: "-32768"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetInt16(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_SetInt32(t *testing.T) {
var cases = []struct {
name string
in int32
want string
}{
{name: "TestIntSetInt32Negative", in: -1, want: "-1"},
{name: "TestIntSetInt32Zero", in: 0, want: "0"},
{name: "TestIntSetInt32Positive", in: 1, want: "1"},
{name: "TestIntSetInt32Max", in: 2147483647, want: "2147483647"},
{name: "TestIntSetInt32Min", in: -2147483648, want: "-2147483648"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetInt32(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_SetInt64(t *testing.T) {
var cases = []struct {
name string
in int64
want string
}{
{name: "TestIntSetInt64Negative", in: -1, want: "-1"},
{name: "TestIntSetInt64Zero", in: 0, want: "0"},
{name: "TestIntSetInt64Positive", in: 1, want: "1"},
{name: "TestIntSetInt64Max", in: 9223372036854775807, want: "9223372036854775807"},
{name: "TestIntSetInt64Min", in: -9223372036854775808, want: "-9223372036854775808"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetInt64(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_SetUint(t *testing.T) {
var cases = []struct {
name string
in uint64
want string
}{
{name: "TestIntSetUintNegative", in: 0, want: "0"},
{name: "TestIntSetUintZero", in: 0, want: "0"},
{name: "TestIntSetUintPositive", in: 1, want: "1"},
{name: "TestIntSetUintMax", in: 18446744073709551615, want: "18446744073709551615"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetUint64(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_SetUint8(t *testing.T) {
var cases = []struct {
name string
in uint8
want string
}{
{name: "TestIntSetUint8Negative", in: 0, want: "0"},
{name: "TestIntSetUint8Zero", in: 0, want: "0"},
{name: "TestIntSetUint8Positive", in: 1, want: "1"},
{name: "TestIntSetUint8Max", in: 255, want: "255"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetUint8(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_SetUint16(t *testing.T) {
var cases = []struct {
name string
in uint16
want string
}{
{name: "TestIntSetUint16Negative", in: 0, want: "0"},
{name: "TestIntSetUint16Zero", in: 0, want: "0"},
{name: "TestIntSetUint16Positive", in: 1, want: "1"},
{name: "TestIntSetUint16Max", in: 65535, want: "65535"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetUint16(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_SetUint32(t *testing.T) {
var cases = []struct {
name string
in uint32
want string
}{
{name: "TestIntSetUint32Negative", in: 0, want: "0"},
{name: "TestIntSetUint32Zero", in: 0, want: "0"},
{name: "TestIntSetUint32Positive", in: 1, want: "1"},
{name: "TestIntSetUint32Max", in: 4294967295, want: "4294967295"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetUint32(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_SetUint64(t *testing.T) {
var cases = []struct {
name string
in uint64
want string
}{
{name: "TestIntSetUint64Negative", in: 0, want: "0"},
{name: "TestIntSetUint64Zero", in: 0, want: "0"},
{name: "TestIntSetUint64Positive", in: 1, want: "1"},
{name: "TestIntSetUint64Max", in: 18446744073709551615, want: "18446744073709551615"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetUint64(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_SetFloat32(t *testing.T) {
var cases = []struct {
name string
in float32
want string
}{
{name: "TestIntSetFloat32Negative", in: -1.1, want: "-1"},
{name: "TestIntSetFloat32Zero", in: 0, want: "0"},
{name: "TestIntSetFloat32Positive", in: 1.1, want: "1"},
{name: "TestIntSetFloat32Max", in: 9223372036854775807, want: "9223372036854775807"},
{name: "TestIntSetFloat32Min", in: -9223372036854775808, want: "-9223372036854775808"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetFloat32(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_SetFloat64(t *testing.T) {
var cases = []struct {
name string
in float64
want string
}{
{name: "TestIntSetFloat64Negative", in: -1.1, want: "-1"},
{name: "TestIntSetFloat64Zero", in: 0, want: "0"},
{name: "TestIntSetFloat64Positive", in: 1.1, want: "1"},
{name: "TestIntSetFloat64Max", in: 9223372036854775807, want: "9223372036854775807"},
{name: "TestIntSetFloat64Min", in: -9223372036854775808, want: "-9223372036854775808"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetFloat64(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_SetBool(t *testing.T) {
var cases = []struct {
name string
in bool
want string
}{
{name: "TestIntSetBoolFalse", in: false, want: "0"},
{name: "TestIntSetBoolTrue", in: true, want: "1"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetBool(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
func TestInt_IsZero(t *testing.T) {
var cases = []struct {
name string
in int64
want bool
}{
{name: "TestIntIsZeroNegative", in: -1, want: false},
{name: "TestIntIsZeroZero", in: 0, want: true},
{name: "TestIntIsZeroPositive", in: 1, want: false},
{name: "TestIntIsZeroMax", in: 9223372036854775807, want: false},
{name: "TestIntIsZeroMin", in: -9223372036854775808, want: false},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
if got := huge.NewInt(c.in).IsZero(); got != c.want {
t.Fatalf("want: %t, got: %t", c.want, got)
}
})
}
}
func TestInt_ToBigint(t *testing.T) {
var cases = []struct {
name string
in int64
want *big.Int
}{
{name: "TestIntToBigintNegative", in: -1, want: big.NewInt(-1)},
{name: "TestIntToBigintZero", in: 0, want: big.NewInt(0)},
{name: "TestIntToBigintPositive", in: 1, want: big.NewInt(1)},
{name: "TestIntToBigintMax", in: 9223372036854775807, want: big.NewInt(9223372036854775807)},
{name: "TestIntToBigintMin", in: -9223372036854775808, want: big.NewInt(-9223372036854775808)},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
if got := huge.NewInt(c.in).ToBigint(); got.Cmp(c.want) != 0 {
t.Fatalf("want: %s, got: %s", c.want.String(), got.String())
}
})
}
}