From b836e56a4d8b64a9078157b15873a62e42f786dd Mon Sep 17 00:00:00 2001 From: Igor Mikushkin Date: Wed, 29 Aug 2018 02:59:01 +0400 Subject: [PATCH] Using integer operations rather than float in rescale --- decimal.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/decimal.go b/decimal.go index 134ece2..7df48f3 100644 --- a/decimal.go +++ b/decimal.go @@ -361,11 +361,11 @@ func NewFromFloatWithExponent(value float64, exp int32) Decimal { // func (d Decimal) rescale(exp int32) Decimal { d.ensureInitialized() - // NOTE(vadim): must convert exps to float64 before - to prevent overflow - diff := math.Abs(float64(exp) - float64(d.exp)) + // NOTE(vadim): must convert exps to int64 before - to prevent overflow + diff := abs64(int64(exp) - int64(d.exp)) value := new(big.Int).Set(d.value) - expScale := new(big.Int).Exp(tenInt, big.NewInt(int64(diff)), nil) + expScale := new(big.Int).Exp(tenInt, big.NewInt(diff), nil) if exp > d.exp { value = value.Quo(value, expScale) } else if exp < d.exp { @@ -378,6 +378,11 @@ func (d Decimal) rescale(exp int32) Decimal { } } +func abs64(n int64) int64 { + y := n >> 63 + return (n ^ y) - y +} + // Abs returns the absolute value of the decimal. func (d Decimal) Abs() Decimal { d.ensureInitialized()