diff --git a/formatter.go b/formatter.go index c58c364..8b928cc 100644 --- a/formatter.go +++ b/formatter.go @@ -4,6 +4,8 @@ import ( "math" "strconv" "strings" + + "github.com/shopspring/decimal" ) // Formatter stores Money formatting information. @@ -60,8 +62,8 @@ func (f *Formatter) ToMajorUnits(amount int64) float64 { if f.Fraction == 0 { return float64(amount) } - - return float64(amount) / float64(math.Pow10(f.Fraction)) + u, _ := decimal.NewFromInt(amount).Div(decimal.NewFromFloat(math.Pow10(f.Fraction))).Float64() + return u } // abs return absolute value of given integer. diff --git a/go.mod b/go.mod index 6d4223b..bfdba3d 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/Rhymond/go-money go 1.13 + +require github.com/shopspring/decimal v1.3.1 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..3289fec --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= diff --git a/money.go b/money.go index 28fc431..7b300d9 100644 --- a/money.go +++ b/money.go @@ -6,6 +6,8 @@ import ( "errors" "fmt" "math" + + "github.com/shopspring/decimal" ) // Injection points for backward compatibility. @@ -90,7 +92,9 @@ func New(amount int64, code string) *Money { // Always rounding trailing decimals down. func NewFromFloat(amount float64, currency string) *Money { currencyDecimals := math.Pow10(GetCurrency(currency).Fraction) - return New(int64(amount*currencyDecimals), currency) + newCurrencyDecimals := decimal.NewFromFloat(currencyDecimals) + newAmount := decimal.NewFromFloat(amount) + return New(newAmount.Mul(newCurrencyDecimals).IntPart(), currency) } // Currency returns the currency used by Money. diff --git a/money_test.go b/money_test.go index e336998..1c14f93 100644 --- a/money_test.go +++ b/money_test.go @@ -661,6 +661,12 @@ func TestNewFromFloat(t *testing.T) { t.Errorf("Expected %d got %d", 1234, m.amount) } + m = NewFromFloat(136.98, EUR) + + if m.amount != 13698 { + t.Errorf("Expected %d got %d", 13698, m.amount) + } + if m.currency.Code != EUR { t.Errorf("Expected currency %s got %s", EUR, m.currency.Code) }