Skip to content

Commit

Permalink
Merge pull request #5 from govalues/int64-scale-argument
Browse files Browse the repository at this point in the history
amount: Implement scale argument in Int64 method
  • Loading branch information
eapenkin authored Aug 4, 2023
2 parents aa52ef6 + 2d5484e commit af61748
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 41 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## [0.1.1] - 2023-08-04

### Changed

- Implemented 'scale' argument for Amount.Int64 method.

## [0.1.0] - 2023-06-04

### Changed
Expand Down
13 changes: 7 additions & 6 deletions amount.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,13 @@ func (a Amount) Float64() (f float64, ok bool) {
return a.value.Float64()
}

// Int64 returns a pair of int64 values representing the integer part i and the
// Int64 returns a pair of int64 values representing the integer part b and the
// fractional part f of the amount.
// The relationship can be expressed as a = i + f / 10^scale, where the scale
// can be obtained using the [Amount.Scale] method.
// The relationship can be expressed as a = b + f / 10^scale.
// If the result cannot be accurately represented as a pair of int64 values,
// the method returns false.
func (a Amount) Int64() (i int64, f int64, ok bool) {
return a.value.Int64()
func (a Amount) Int64(scale int) (b, f int64, ok bool) {
return a.value.Int64(scale)
}

// Prec returns the number of digits in the coefficient.
Expand Down Expand Up @@ -237,7 +236,7 @@ func (a Amount) Sub(b Amount) (Amount, error) {
d, e := a.value, b.value
f, err := d.SubExact(e, a.Curr().Scale())
if err != nil {
return Amount{}, fmt.Errorf("%q - %q: %w", b, a, err)
return Amount{}, fmt.Errorf("%q - %q: %w", a, b, err)
}
return NewAmount(a.Curr(), f)
}
Expand Down Expand Up @@ -351,6 +350,7 @@ func (a Amount) Split(parts int) ([]Amount, error) {
}
ulp := rem.ULP().CopySign(rem)

// Distribute remainder
res := make([]Amount, parts)
for i := 0; i < parts; i++ {
res[i] = quo
Expand All @@ -365,6 +365,7 @@ func (a Amount) Split(parts int) ([]Amount, error) {
}
}
}

return res, nil
}

Expand Down
52 changes: 20 additions & 32 deletions doc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,23 +91,23 @@ func (s Statement) OutgoingBalance() (money.Amount, error) {

// PercChange method calculates (OutgoingBalance - IncomingBalance) / IncomingBalance
func (s Statement) PercChange() (decimal.Decimal, error) {
start, err := s.IncomingBalance()
inc, err := s.IncomingBalance()
if err != nil {
return decimal.Decimal{}, err
}
end, err := s.OutgoingBalance()
out, err := s.OutgoingBalance()
if err != nil {
return decimal.Decimal{}, err
}
delta, err := end.Sub(start)
diff, err := out.Sub(inc)
if err != nil {
return decimal.Decimal{}, err
}
ratio, err := delta.Rat(start)
rat, err := diff.Rat(inc)
if err != nil {
return decimal.Decimal{}, err
}
return ratio, nil
return rat, nil
}

func (s Statement) TotalInterest() (money.Amount, error) {
Expand Down Expand Up @@ -482,16 +482,20 @@ func ExampleAmount_Float64() {
}

func ExampleAmount_Int64() {
a := money.MustParseAmount("JPY", "100")
b := money.MustParseAmount("USD", "15.60")
c := money.MustParseAmount("OMR", "2.389")
fmt.Println(a.Int64())
fmt.Println(b.Int64())
fmt.Println(c.Int64())
a := money.MustParseAmount("USD", "15.67")
fmt.Println(a.Int64(5))
fmt.Println(a.Int64(4))
fmt.Println(a.Int64(3))
fmt.Println(a.Int64(2))
fmt.Println(a.Int64(1))
fmt.Println(a.Int64(0))
// Output:
// 100 0 true
// 15 60 true
// 2 389 true
// 15 67000 true
// 15 6700 true
// 15 670 true
// 15 67 true
// 15 7 true
// 16 0 true
}

func ExampleAmount_Prec() {
Expand Down Expand Up @@ -1051,28 +1055,12 @@ func ParseMoneyProto(curr string, units int64, nanos int32) (money.Amount, error
if err != nil {
return money.Amount{}, err
}
// Units
if units > 0 && nanos < 0 || units < 0 && nanos > 0 {
return money.Amount{}, fmt.Errorf("inconsistent signs")
}
u, err := decimal.New(units, 0)
if err != nil {
return money.Amount{}, err
}
// Nanos
if nanos < -999_999_999 || nanos > 999_999_999 {
return money.Amount{}, fmt.Errorf("inconsistent nanos")
}
n, err := decimal.New(int64(nanos), 9)
if err != nil {
return money.Amount{}, err
}
n = n.Trim(c.Scale())
// Amount
d, err := u.AddExact(n, c.Scale())
d, err := decimal.NewFromInt64(units, int64(nanos), 9)
if err != nil {
return money.Amount{}, err
}
d = d.Trim(c.Scale())
return money.NewAmount(c, d)
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ module github.com/govalues/money

go 1.19

require github.com/govalues/decimal v0.1.0
require github.com/govalues/decimal v0.1.4
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
github.com/govalues/decimal v0.1.0 h1:nQmM1pazhEmA3xLNn917uiealPyCYNc1vtyPXPll2Y4=
github.com/govalues/decimal v0.1.0/go.mod h1:NfqNdX/GQBotCdmXtzckjhq54itVCX1Git3psSgom8A=
github.com/govalues/decimal v0.1.4 h1:MbFSBjswROtTZhsK3Fvbamn2IutpMoUSqDyD8mejuFg=
github.com/govalues/decimal v0.1.4/go.mod h1:NfqNdX/GQBotCdmXtzckjhq54itVCX1Git3psSgom8A=

0 comments on commit af61748

Please sign in to comment.