mirror of
https://github.com/shopspring/decimal.git
synced 2024-11-23 04:40:49 +01:00
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:
parent
69b3a8ad1f
commit
2df3e6ddaf
2 changed files with 41 additions and 0 deletions
12
decimal.go
12
decimal.go
|
@ -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
|
// Div returns d / d2. If it doesn't divide exactly, the result will have
|
||||||
// DivisionPrecision digits after the decimal point.
|
// DivisionPrecision digits after the decimal point.
|
||||||
func (d Decimal) Div(d2 Decimal) Decimal {
|
func (d Decimal) Div(d2 Decimal) Decimal {
|
||||||
|
|
|
@ -925,6 +925,7 @@ func TestDecimal_Uninitialized(t *testing.T) {
|
||||||
a.Add(b),
|
a.Add(b),
|
||||||
a.Sub(b),
|
a.Sub(b),
|
||||||
a.Mul(b),
|
a.Mul(b),
|
||||||
|
a.Shift(0),
|
||||||
a.Div(New(1, -1)),
|
a.Div(New(1, -1)),
|
||||||
a.Round(2),
|
a.Round(2),
|
||||||
a.Floor(),
|
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) {
|
func TestDecimal_Div(t *testing.T) {
|
||||||
type Inp struct {
|
type Inp struct {
|
||||||
a string
|
a string
|
||||||
|
|
Loading…
Reference in a new issue