From 1884f454f8eac1ab73620d725efc7f4ecf42238c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Wo=C5=9B?= Date: Mon, 20 Apr 2020 00:29:39 +0200 Subject: [PATCH] Add new helper methods: BigInt, BigFloat (#171) * Add new helper methods: BigInt, BigFloat * Add few tests cases showing loss of precision after casting --- decimal.go | 16 +++++++++++++++ decimal_test.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/decimal.go b/decimal.go index b78581b..6a986b2 100644 --- a/decimal.go +++ b/decimal.go @@ -695,6 +695,22 @@ func (d Decimal) IntPart() int64 { return scaledD.value.Int64() } +// BigInt returns integer component of the decimal as a BigInt. +func (d Decimal) BigInt() *big.Int { + scaledD := d.rescale(0) + i := &big.Int{} + i.SetString(scaledD.String(), 10) + return i +} + +// BigFloat returns decimal as BigFloat. +// Be aware that casting decimal to BigFloat might cause a loss of precision. +func (d Decimal) BigFloat() *big.Float { + f := &big.Float{} + f.SetString(d.String()) + return f +} + // Rat returns a rational number representation of the decimal. func (d Decimal) Rat() *big.Rat { d.ensureInitialized() diff --git a/decimal_test.go b/decimal_test.go index c684335..9841720 100644 --- a/decimal_test.go +++ b/decimal_test.go @@ -1724,6 +1724,59 @@ func TestIntPart(t *testing.T) { } } +func TestBigInt(t *testing.T) { + testCases := []struct { + Dec string + BigIntRep 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) + } + if d.BigInt().String() != testCase.BigIntRep { + t.Errorf("expect %s, got %s", testCase.BigIntRep, d.BigInt()) + } + } +} + +func TestBigFloat(t *testing.T) { + testCases := []struct { + Dec string + BigFloatRep string + }{ + {"0.0", "0"}, + {"0.00000", "0"}, + {"0.01", "0.01"}, + {"12.1", "12.1"}, + {"9999.999", "9999.999"}, + {"-32768.01234", "-32768.01234"}, + {"-572372.0000000001", "-572372"}, + {"512.012345123451234512345", "512.0123451"}, + {"1.010101010101010101010101010101", "1.01010101"}, + {"55555555.555555555555555555555", "55555555.56"}, + } + + for _, testCase := range testCases { + d, err := NewFromString(testCase.Dec) + if err != nil { + t.Fatal(err) + } + if d.BigFloat().String() != testCase.BigFloatRep { + t.Errorf("expect %s, got %s", testCase.BigFloatRep, d.BigFloat()) + } + } +} + func TestDecimal_Min(t *testing.T) { // the first element in the array is the expected answer, rest are inputs testCases := [][]float64{