feat: huge 包 NewInt 函数支持 string、bool、float 类型
This commit is contained in:
parent
9dba7ffe19
commit
c4605cc4c3
|
@ -17,33 +17,70 @@ var (
|
|||
|
||||
type Int big.Int
|
||||
|
||||
// NewInt 创建一个 Int
|
||||
func NewInt[T generic.Number](x T) *Int {
|
||||
return (*Int)(big.NewInt(int64(x)))
|
||||
}
|
||||
|
||||
// NewIntByString 通过字符串创建一个 Int
|
||||
// - 如果字符串不是一个合法的数字,则返回 0
|
||||
func NewIntByString(i string) *Int {
|
||||
v, suc := new(big.Int).SetString(i, 10)
|
||||
if !suc {
|
||||
return IntZero.Copy()
|
||||
// NewInt 创建一个 Int 对象,该对象的值为 x
|
||||
func NewInt[T generic.Basic](x T) *Int {
|
||||
var xa any = x
|
||||
switch x := xa.(type) {
|
||||
case int:
|
||||
return (*Int)(big.NewInt(int64(x)))
|
||||
case int8:
|
||||
return (*Int)(big.NewInt(int64(x)))
|
||||
case int16:
|
||||
return (*Int)(big.NewInt(int64(x)))
|
||||
case int32:
|
||||
return (*Int)(big.NewInt(int64(x)))
|
||||
case int64:
|
||||
return (*Int)(big.NewInt(x))
|
||||
case uint:
|
||||
return (*Int)(big.NewInt(int64(x)))
|
||||
case uint8:
|
||||
return (*Int)(big.NewInt(int64(x)))
|
||||
case uint16:
|
||||
return (*Int)(big.NewInt(int64(x)))
|
||||
case uint32:
|
||||
return (*Int)(big.NewInt(int64(x)))
|
||||
case uint64:
|
||||
return (*Int)(big.NewInt(int64(x)))
|
||||
case string:
|
||||
si, suc := new(big.Int).SetString(x, 10)
|
||||
if !suc {
|
||||
return (*Int)(big.NewInt(0))
|
||||
}
|
||||
return (*Int)(si)
|
||||
case bool:
|
||||
if x {
|
||||
return (*Int)(big.NewInt(1))
|
||||
}
|
||||
return (*Int)(big.NewInt(0))
|
||||
case float32:
|
||||
return (*Int)(big.NewInt(int64(x)))
|
||||
case float64:
|
||||
return (*Int)(big.NewInt(int64(x)))
|
||||
}
|
||||
return (*Int)(v)
|
||||
return (*Int)(big.NewInt(0))
|
||||
}
|
||||
|
||||
// applyIntOperation 应用一个 Int 操作
|
||||
func applyIntOperation[T generic.Number](v *Int, i T, op func(*big.Int, *big.Int) *big.Int) *Int {
|
||||
return (*Int)(op(v.ToBigint(), NewInt(i).ToBigint()))
|
||||
}
|
||||
|
||||
// Copy 拷贝当前 Int 对象
|
||||
func (slf *Int) Copy() *Int {
|
||||
return (*Int)(new(big.Int).Set(slf.ToBigint()))
|
||||
}
|
||||
|
||||
// Set 设置当前 Int 对象的值为 i
|
||||
func (slf *Int) Set(i *Int) *Int {
|
||||
return (*Int)(slf.ToBigint().Set(i.ToBigint()))
|
||||
}
|
||||
|
||||
// SetString 设置当前 Int 对象的值为 i
|
||||
func (slf *Int) SetString(i string) *Int {
|
||||
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
|
||||
}
|
||||
|
||||
// SetInt 设置当前 Int 对象的值为 i
|
||||
func (slf *Int) SetInt(i int) *Int {
|
||||
return (*Int)(slf.ToBigint().Set((*big.Int)(NewInt(i))))
|
||||
}
|
||||
|
@ -92,6 +129,9 @@ func (slf *Int) IsZero() bool {
|
|||
}
|
||||
|
||||
func (slf *Int) ToBigint() *big.Int {
|
||||
if slf == nil {
|
||||
return big.NewInt(0)
|
||||
}
|
||||
return (*big.Int)(slf)
|
||||
}
|
||||
|
||||
|
@ -130,6 +170,9 @@ func (slf *Int) Int64() int64 {
|
|||
}
|
||||
|
||||
func (slf *Int) String() string {
|
||||
if slf == nil {
|
||||
return "0"
|
||||
}
|
||||
return slf.ToBigint().String()
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package huge_test
|
||||
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/utils/huge"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewInt(t *testing.T) {
|
||||
var cases = []struct {
|
||||
name string
|
||||
nil bool
|
||||
in int64
|
||||
mul int64
|
||||
want string
|
||||
}{
|
||||
{name: "TestNewIntNegative", in: -1, want: "-1"},
|
||||
{name: "TestNewIntZero", in: 0, want: "0"},
|
||||
{name: "TestNewIntPositive", in: 1, want: "1"},
|
||||
{name: "TestNewIntMax", in: 9223372036854775807, want: "9223372036854775807"},
|
||||
{name: "TestNewIntMin", in: -9223372036854775808, want: "-9223372036854775808"},
|
||||
{name: "TestNewIntMulNegative", in: -9223372036854775808, mul: 10000000, want: "-92233720368547758080000000"},
|
||||
{name: "TestNewIntMulPositive", in: 9223372036854775807, mul: 10000000, want: "92233720368547758070000000"},
|
||||
{name: "TestNewIntNil", nil: true, want: "0"},
|
||||
{name: "TestNewIntNilMul", nil: true, mul: 10000000, want: "0"},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
var got *huge.Int
|
||||
switch {
|
||||
case c.nil:
|
||||
if c.mul > 0 {
|
||||
got = huge.NewInt(0).MulInt64(c.mul)
|
||||
}
|
||||
case c.mul == 0:
|
||||
got = huge.NewInt(c.in)
|
||||
default:
|
||||
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())
|
||||
} else {
|
||||
t.Log(s)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// other
|
||||
t.Run("TestNewIntFromString", func(t *testing.T) {
|
||||
if got := huge.NewInt("1234567890123456789012345678901234567890"); got.String() != "1234567890123456789012345678901234567890" {
|
||||
t.Fatalf("want: %s, got: %s", "1234567890123456789012345678901234567890", got.String())
|
||||
}
|
||||
})
|
||||
t.Run("TestNewIntFromInt", func(t *testing.T) {
|
||||
if got := huge.NewInt(1234567890); got.String() != "1234567890" {
|
||||
t.Fatalf("want: %s, got: %s", "1234567890", got.String())
|
||||
}
|
||||
})
|
||||
t.Run("TestNewIntFromBool", func(t *testing.T) {
|
||||
if got := huge.NewInt(true); got.String() != "1" {
|
||||
t.Fatalf("want: %s, got: %s", "1", got.String())
|
||||
}
|
||||
})
|
||||
t.Run("TestNewIntFromFloat", func(t *testing.T) {
|
||||
if got := huge.NewInt(1234567890.1234567890); got.String() != "1234567890" {
|
||||
t.Fatalf("want: %s, got: %s", "1234567890", got.String())
|
||||
}
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue