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.
This commit is contained in:
Steven Roose 2018-03-19 18:08:23 +01:00 committed by Victor Quinn
parent 69b3a8ad1f
commit 2df3e6ddaf
2 changed files with 41 additions and 0 deletions

View file

@ -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 {

View file

@ -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