Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[patch] added new operation "Allocate" instead of Divide and deprecated Divide. #5

Merged
merged 1 commit into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 33 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

Currency package helps you do currency computations accurately. `Currency` struct holds all the data required to define a currency.

```
```golang
type Currency struct {
// Code represents the international currency code
Code string
Expand All @@ -35,7 +35,7 @@ type Currency struct {

### New(main int, fractional int, code, symbol string, funame string, fushare uint)

New returns a pointer of currency instance created based on the values provided
New returns a pointer of currency instance created based on the configuration.

```
main - Main/Super unit of the currency
Expand All @@ -56,7 +56,7 @@ _IMPORTANT! Fractional unit can be negative only when the main value is 0. If th

### Computational methods

IMPORTANT: Computation is supported only between same type of currencies (i.e. currency codes should be same)
IMPORTANT: Computation is supported only between same type of currencies (i.e. currency codes _*must*_ match)

1. `c1.Add(c2 currency)` add c2 to c1, and update c1
2. `c1.AddInt(main int, fractional int)` add the currency equivalent of the main & fractional int to c1
Expand All @@ -67,12 +67,12 @@ IMPORTANT: Computation is supported only between same type of currencies (i.e. c
7. `c1.UpdateWithFractional(ftotal int)` would update the the value of c1, where _ftotal_ is the total value of the currency in fractional unit. e.g. INR, `UpdateWithFractional(100)` would set the main value as `1` and fractional unit as `0`
8. `c1.FractionalTotal() int` returns the total value of the currency in its fractional unit. e.g. INR, if the Main value is `1` and fractional unit is `0`, it would return `100`, i.e. 100 paise
9. `c1.Percent(n float64) currency` returns a new currency instance which is n percentage of c1
10. `c1.Divide(n int, retain bool)[]currency, ok ` returns a slice of currency of size n. `ok` if returned as `true` means the currency value was perfectly divisible by n. If `retain` is true,
then `c1` will have the remainder value after dividing otherwise it is distributed among the returned currencies.
10. `c1.Allocate(n int, retain bool)[]currency, ok ` returns a slice of currency of size n. `ok` if **true** means the currency value is fully divisible by n. If `retain` is true,
then `c1` will have the remainder value after allocation, otherwise the remainder is distributed among the returned currencies.

#### Why does `Divide(n int, retain bool)` return a slice of currencies?
#### Why does `Allocate(n int, retain bool)` return a slice of currencies?

`Divide` unlike other operations, cannot be rounded off. If it is rounded, it would result in currency peddling.
`Allocate` unlike other operations, cannot be rounded off. If it is rounded, it would result in currency _peddling_.

e.g. ₹1/- (INR 1) is to be divided by 3. There are 2 options of dividing this by 3.

Expand All @@ -91,26 +91,34 @@ How to run?

`$ go test -bench=.`

Results when run on a MacBook Pro (13-inch, Early 2015), CPU: 2.7 GHz Intel Core i5, RAM: 8 GB 1867 MHz DDR3, Graphics: Intel Iris Graphics 6100 1536 MB
Results when run on a MacBook Pro (13-inch, M3, 2024), CPU: Apple M3, RAM: 24 GB

```
BenchmarkNew-4 20000000 67.3 ns/op
BenchmarkNewFractional-4 20000000 65.9 ns/op
BenchmarkParseFloat64-4 20000000 87.4 ns/op
BenchmarkParseString-4 3000000 544 ns/op
BenchmarkString-4 10000000 211 ns/op
BenchmarkStringNoPrefix-4 10000000 164 ns/op
BenchmarkFloat64-4 2000000000 0.34 ns/op
BenchmarkFractionalTotal-4 2000000000 0.33 ns/op
BenchmarkUpdateWithFractional-4 100000000 10.3 ns/op
BenchmarkAdd-4 100000000 20.8 ns/op
BenchmarkAddInt-4 100000000 18.9 ns/op
BenchmarkSubtract-4 100000000 21.2 ns/op
BenchmarkSubtractInt-4 100000000 18.3 ns/op
BenchmarkMultiply-4 100000000 16.2 ns/op
BenchmarkMultiplyFloat64-4 50000000 30.1 ns/op
BenchmarkPercent-4 20000000 67.1 ns/op
BenchmarkDivide-4 10000000 155 ns/op
go version go1.23.1 darwin/arm64
github.com/naughtygopher/currency [allocate]$ go test -bench .
goos: darwin
goarch: arm64
pkg: github.com/naughtygopher/currency/v2
cpu: Apple M3
BenchmarkNew-8 55541650 21.68 ns/op
BenchmarkNewFractional-8 58322852 21.69 ns/op
BenchmarkParseFloat64-8 47724391 25.72 ns/op
BenchmarkParseString-8 6650085 182.2 ns/op
BenchmarkString-8 20838006 58.65 ns/op
BenchmarkStringNoPrefix-8 30418314 39.87 ns/op
BenchmarkFloat64-8 1000000000 0.2722 ns/op
BenchmarkFractionalTotal-8 1000000000 0.2697 ns/op
BenchmarkUpdateWithFractional-8 1000000000 1.068 ns/op
BenchmarkAdd-8 190538139 6.245 ns/op
BenchmarkAddInt-8 230544486 5.690 ns/op
BenchmarkSubtract-8 185860339 6.537 ns/op
BenchmarkSubtractInt-8 217542852 5.571 ns/op
BenchmarkMultiply-8 282455095 4.335 ns/op
BenchmarkMultiplyFloat64-8 84543258 13.13 ns/op
BenchmarkPercent-8 52612252 21.28 ns/op
BenchmarkAllocate-8 35645416 34.41 ns/op
PASS
ok github.com/naughtygopher/currency/v2 23.125s
```

## References
Expand Down
19 changes: 13 additions & 6 deletions operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,20 @@ func (c *Currency) MultiplyFloat64(by float64) {
c.UpdateWithFractional(round(t, c.magnitude))
}

// Divide divides the currency by the given integer and returns a list of currencies and bool.
// If `retain` is set as true, the balance will not be distributed among the splits, instead
// retained inside c.
// It returns a list because, when the currency cannot be split/divided equally,
// then the remainder has to be distributed. The bool value if `true`, means the currency was
// split equally.
// Divide is a deprecated method which does allocations
// Deprecated: Divide is not the technical term when dealing with currency.
func (c *Currency) Divide(by int, retain bool) ([]Currency, bool) {
return c.Allocate(by, retain)
}

// Allocate does fair allocation of the currency by the given integer and returns a list of currencies and bool.
/*
If `retain` is set as true, the balance will not be distributed among the splits,
instead retained inside c. It returns a list because, when the currency cannot
be split/divided equally, then the remainder has to be distributed.
The bool value if `true`, means the currency was split equally.
*/
func (c *Currency) Allocate(by int, retain bool) ([]Currency, bool) {
sE := false

ft := c.FractionalTotal()
Expand Down
4 changes: 2 additions & 2 deletions operations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,9 @@ func BenchmarkPercent(t *testing.B) {
}
}

func BenchmarkDivide(t *testing.B) {
func BenchmarkAllocate(t *testing.B) {
cur, _ := New(9999, 0, "INR", "₹", "paise", 100)
for i := 0; i < t.N; i++ {
_, _ = cur.Divide(2, true)
_, _ = cur.Allocate(2, true)
}
}
Loading