add uint support

This commit is contained in:
Elias Van Ootegem 2021-07-05 15:57:32 +01:00
parent cc4584f0a5
commit aaa563729a
3 changed files with 81 additions and 0 deletions

View file

@ -25,6 +25,8 @@ import (
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
"github.com/holiman/uint256"
) )
// DivisionPrecision is the number of decimal places in the result when it // DivisionPrecision is the number of decimal places in the result when it
@ -98,6 +100,29 @@ func NewFromInt(value int64) Decimal {
} }
} }
// NewFromUint converts a uint256.Int to Decimal.
// Example:
//
// NewFromInt(uint256.NewInt(123)).String() // output: "123"
func NewFromUint(u *uint256.Int) Decimal {
return Decimal{
value: u.ToBig(),
exp: 0,
}
}
// NewFromUintExp converts a Uint to Decimal with given exponent
//
// Example:
//
// NewFromInt(uint256.NewInt(1), 2).String() // output: "100"
func NewFromUintExp(u *uint256.Int, exp int32) Decimal {
return Decimal{
value: u.ToBig(),
exp: exp,
}
}
// NewFromInt32 converts a int32 to Decimal. // NewFromInt32 converts a int32 to Decimal.
// //
// Example: // Example:
@ -797,6 +822,21 @@ func (d Decimal) Rat() *big.Rat {
return new(big.Rat).SetFrac(num, oneInt) return new(big.Rat).SetFrac(num, oneInt)
} }
// Uint returns integer component of the decimal as a uint256.Int.
func (d Decimal) Uint() (*uint256.Int, bool) {
i := &big.Int{}
i.SetString(d.rescale(0).String(), 10)
return uint256.FromBig(i)
}
// UintNO returns integer component of the decimal as a uint256.Int.
// NO stands for No Overflow. Ignore the bool indicating whether or not
// overflow occured.
func (d Decimal) UintNO() *uint256.Int {
u, _ := d.Uint()
return u
}
// Float64 returns the nearest float64 value for d and a bool indicating // Float64 returns the nearest float64 value for d and a bool indicating
// whether f represents d exactly. // whether f represents d exactly.
// For more details, see the documentation for big.Rat.Float64 // For more details, see the documentation for big.Rat.Float64

View file

@ -15,6 +15,8 @@ import (
"testing" "testing"
"testing/quick" "testing/quick"
"time" "time"
"github.com/holiman/uint256"
) )
type testEnt struct { type testEnt struct {
@ -2241,6 +2243,43 @@ func TestBigInt(t *testing.T) {
} }
} }
func TestUint(t *testing.T) {
testCases := []struct {
Dec string
UintRep string
}{
{"0.0", "0"},
{"0.00000", "0"},
{"0.01", "0"},
{"12.1", "12"},
{"9999.999", "9999"},
// {"-32768.01234", "-32768"},
// {"-572372.0000000001", "-572372"},
}
for _, testCase := range testCases {
d, err := NewFromString(testCase.Dec)
if err != nil {
t.Fatal(err)
}
bi := &big.Int{}
bi.SetString(testCase.UintRep, 10)
exp, ok := uint256.FromBig(bi)
got, ok2 := d.Uint()
if ok != ok2 {
t.Fatalf("overflow from string (%v) <> vs from decimal (%v)", ok, ok2)
}
if !exp.Eq(got) {
t.Fatalf("expected %s == %s", exp, got)
}
if !ok {
if got = d.UintNO(); !exp.Eq(got) {
t.Fatalf("UintNO: expected %s == %s", exp, got)
}
}
}
}
func TestBigFloat(t *testing.T) { func TestBigFloat(t *testing.T) {
testCases := []struct { testCases := []struct {
Dec string Dec string

2
go.mod
View file

@ -1,3 +1,5 @@
module github.com/shopspring/decimal module github.com/shopspring/decimal
go 1.13 go 1.13
require github.com/holiman/uint256 v1.2.0 // indirect