Skip to content

Commit

Permalink
Merge pull request #14 from jon4hz/main
Browse files Browse the repository at this point in the history
Fix ToSignificant() output on very small numbers
  • Loading branch information
miraclesu authored Nov 15, 2021
2 parents 228c69e + c4cca6f commit da9a2f7
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 17 deletions.
28 changes: 22 additions & 6 deletions entities/fraction.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ package entities

import (
"math/big"
"strings"

"github.com/shopspring/decimal"

"github.com/miraclesu/uniswap-sdk-go/constants"
"github.com/miraclesu/uniswap-sdk-go/number"
)

var (
// ZeroFraction zero fraction instance
ZeroFraction = NewFraction(constants.Zero, nil)
)
// ZeroFraction zero fraction instance
var ZeroFraction = NewFraction(constants.Zero, nil)

const decimalSplitLength = 2

// Fraction warps math franction
type Fraction struct {
Expand Down Expand Up @@ -120,16 +121,31 @@ func (f *Fraction) Divide(other *Fraction) *Fraction {
func (f *Fraction) ToSignificant(significantDigits uint, opt ...number.Option) string {
f.opts = number.New(number.WithGroupSeparator('\xA0'), number.WithRoundingMode(constants.RoundHalfUp))
f.opts.Apply(opt...)
f.opts.Apply(number.WithRoundingPrecision(int(significantDigits)))

d := decimal.NewFromBigInt(f.Numerator, 0).Div(decimal.NewFromBigInt(f.Denominator, 0))
if d.LessThan(decimal.New(1, 0)) {
significantDigits += countZerosAfterDecimalPoint(d.String())
}
f.opts.Apply(number.WithRoundingPrecision(int(significantDigits)))
if v, err := number.DecimalRound(d, f.opts); err == nil {
d = v
}

return number.DecimalFormat(d, f.opts)
}

func countZerosAfterDecimalPoint(d string) uint {
grp := strings.Split(d, ".")
if len(grp) != decimalSplitLength {
return 0
}
for i, v := range grp[1] {
if v != '0' {
return uint(i)
}
}
return 0
}

// ToFixed format output
func (f *Fraction) ToFixed(decimalPlaces uint, opt ...number.Option) string {
f.opts = number.New(number.WithGroupSeparator('\xA0'), number.WithRoundingMode(constants.RoundHalfUp))
Expand Down
23 changes: 12 additions & 11 deletions entities/fraction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

func TestQuotient(t *testing.T) {
var tests = []struct {
tests := []struct {
Input [2]int64
Output int64
}{
Expand All @@ -23,7 +23,7 @@ func TestQuotient(t *testing.T) {
}

func TestRemainder(t *testing.T) {
var tests = []struct {
tests := []struct {
Input [2]int64
Output [2]int64
}{
Expand All @@ -41,7 +41,7 @@ func TestRemainder(t *testing.T) {
}

func TestInvert(t *testing.T) {
var tests = []struct {
tests := []struct {
Input [2]int64
Output [2]int64
}{
Expand All @@ -56,7 +56,7 @@ func TestInvert(t *testing.T) {
}

func TestAdd(t *testing.T) {
var tests = []struct {
tests := []struct {
Input [4]int64
Output [2]int64
}{
Expand All @@ -75,7 +75,7 @@ func TestAdd(t *testing.T) {
}

func TestSubtract(t *testing.T) {
var tests = []struct {
tests := []struct {
Input [4]int64
Output [2]int64
}{
Expand All @@ -94,7 +94,7 @@ func TestSubtract(t *testing.T) {
}

func TestLessThan(t *testing.T) {
var tests = []struct {
tests := []struct {
Input [4]int64
Output bool
}{
Expand All @@ -112,7 +112,7 @@ func TestLessThan(t *testing.T) {
}

func TestEqualTo(t *testing.T) {
var tests = []struct {
tests := []struct {
Input [4]int64
Output bool
}{
Expand All @@ -131,7 +131,7 @@ func TestEqualTo(t *testing.T) {
}

func TestGreaterThan(t *testing.T) {
var tests = []struct {
tests := []struct {
Input [4]int64
Output bool
}{
Expand All @@ -151,7 +151,7 @@ func TestGreaterThan(t *testing.T) {
}

func TestMultiply(t *testing.T) {
var tests = []struct {
tests := []struct {
Input [4]int64
Output [2]int64
}{
Expand All @@ -171,7 +171,7 @@ func TestMultiply(t *testing.T) {
}

func TestDivide(t *testing.T) {
var tests = []struct {
tests := []struct {
Input [4]int64
Output [2]int64
}{
Expand All @@ -192,7 +192,7 @@ func TestDivide(t *testing.T) {
}

func TestToSignificant(t *testing.T) {
var tests = []struct {
tests := []struct {
Input [2]int64
Output string
Format uint
Expand All @@ -203,6 +203,7 @@ func TestToSignificant(t *testing.T) {
{[2]int64{126, 100}, "1.26", 2},
{[2]int64{124, 100}, "1.2", 1},
{[2]int64{124, 100}, "1.24", 2},
{[2]int64{125, 1000000000}, "0.00000013", 2},
}
for i, test := range tests {
output := NewFraction(big.NewInt(test.Input[0]), big.NewInt(test.Input[1])).ToSignificant(test.Format)
Expand Down

0 comments on commit da9a2f7

Please sign in to comment.