diff options
author | Steven Roose <stevenroose@gmail.com> | 2018-03-20 01:08:23 +0800 |
---|---|---|
committer | Victor Quinn <mail@victorquinn.com> | 2018-03-20 01:08:23 +0800 |
commit | 2df3e6ddaf6e9531dd02d7b6337f2d310f5e4f22 (patch) | |
tree | b3a358a7ea14356e29d2b18a655eb5bb2bbedc16 | |
parent | 69b3a8ad1f5f2c8bd855cb6506d18593064a346b (diff) | |
download | dexon-decimal-2df3e6ddaf6e9531dd02d7b6337f2d310f5e4f22.tar.gz dexon-decimal-2df3e6ddaf6e9531dd02d7b6337f2d310f5e4f22.tar.zst dexon-decimal-2df3e6ddaf6e9531dd02d7b6337f2d310f5e4f22.zip |
Add support for shifting in base 10 (#86)
This allows for very fast multiplying and dividing by powers of 10
without the possibility of losing precision.
-rw-r--r-- | decimal.go | 12 | ||||
-rw-r--r-- | decimal_test.go | 29 |
2 files changed, 41 insertions, 0 deletions
@@ -376,6 +376,18 @@ func (d Decimal) Mul(d2 Decimal) Decimal { } } +// Shift shifts the decimal in base 10. +// It shifts left when shift is positive and right if shift is negative. +// In simpler terms, the given value for shift is added to the exponent +// of the decimal. +func (d Decimal) Shift(shift int32) Decimal { + d.ensureInitialized() + return Decimal{ + value: new(big.Int).Set(d.value), + exp: d.exp + shift, + } +} + // Div returns d / d2. If it doesn't divide exactly, the result will have // DivisionPrecision digits after the decimal point. func (d Decimal) Div(d2 Decimal) Decimal { diff --git a/decimal_test.go b/decimal_test.go index 25ad751..ac80089 100644 --- a/decimal_test.go +++ b/decimal_test.go @@ -925,6 +925,7 @@ func TestDecimal_Uninitialized(t *testing.T) { a.Add(b), a.Sub(b), a.Mul(b), + a.Shift(0), a.Div(New(1, -1)), a.Round(2), a.Floor(), @@ -1096,6 +1097,34 @@ func TestDecimal_Mul(t *testing.T) { } } +func TestDecimal_Shift(t *testing.T) { + type Inp struct { + a string + b int32 + } + + inputs := map[Inp]string{ + Inp{"6", 3}: "6000", + Inp{"10", -2}: "0.1", + Inp{"2.2", 1}: "22", + Inp{"-2.2", -1}: "-0.22", + Inp{"12.88", 5}: "1288000", + Inp{"-10234274355545544493", -3}: "-10234274355545544.493", + Inp{"-4612301402398.4753343454", 5}: "-461230140239847533.43454", + } + + for inp, expectedStr := range inputs { + num, _ := NewFromString(inp.a) + + got := num.Shift(inp.b) + expected, _ := NewFromString(expectedStr) + if !got.Equal(expected) { + t.Errorf("expected %v when shifting %v by %v, got %v", + expected, num, inp.b, got) + } + } +} + func TestDecimal_Div(t *testing.T) { type Inp struct { a string |