Last active
June 7, 2022 13:29
-
-
Save bcsmith2846/3f02a33a499cae9b48c7ae799f7ed909 to your computer and use it in GitHub Desktop.
Gravel Decimal and Currency Types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package domain | |
import ( | |
"fmt" | |
"github.com/bojanz/currency" | |
"github.com/cockroachdb/apd" | |
) | |
/* | |
Output: | |
[brenden@1337-lt gravel]$ gore -autoimport -pkg ./internal/domain | |
gore version 0.5.5 :help for help | |
added file internal/domain/address.go | |
added file internal/domain/billing_type.go | |
... | |
gore> TestNumbers() | |
Currency type w/o locale and formatter: 123.45 USD | |
Currency type: $123.45 | |
Conditions: ; Errors: <nil> | |
(float64) .1 + .1 + .1 === .3: false | |
(apd.Decimal) ".1" + ".1" + ".1" == ".3": true | |
(apd.Decimal) ".1" + ".1" + ".1" == (3 * (10^-1)): true | |
(float64) sum (compiler cuts off zeros where precision is lost): 0.300000 | |
(apd.Decimal) sum: 0.3 | |
Percentages: 0.3 -> 30% | |
*/ | |
/* | |
Notes: | |
- Arbitrary precision | |
- Implements sql.driver interface to be stored as a string | |
- Separates errors from "conditions" like undefined numbers, | |
InvalidOperations, etc. | |
- Has a type which will chain operations even after a failure | |
without a panic while still retaining the error condition | |
through the chain which can be displayed at the end | |
*/ | |
type Decimal = *apd.Decimal | |
/* | |
Notes: | |
- Uses the apd.Decimal type in the currency.Amount struct | |
- Implements sql.driver interface to be stored as a composite type | |
containing two string parts: the value and the currency | |
*/ | |
type Currency = currency.Amount | |
const ( | |
CURRENCY = "USD" | |
LOCALE = "en-US" | |
) | |
func TestNumbers() { | |
amount, _ := currency.NewAmount("123.45", CURRENCY) | |
fmt.Printf("Currency type w/o locale and formatter: %s\n", amount.String()) | |
locale := currency.NewLocale(LOCALE) | |
formatter := currency.NewFormatter(locale) | |
localizedString := formatter.Format(currency.Amount(amount)) | |
fmt.Printf("Currency type: %s\n", localizedString) | |
viewInputOne := ".1" | |
var testNumOne float64 | |
testNumOne = 0.1 | |
firstNum, cond, err := apd.NewFromString(viewInputOne) | |
fmt.Printf("Conditions: %s; Errors: %v\n", cond, err) | |
viewInputTwo := ".1" | |
var testNumTwo float64 | |
testNumTwo = 0.1 | |
secondNum, _, _ := apd.NewFromString(viewInputTwo) | |
viewInputThree := ".1" | |
var testNumThree float64 | |
testNumThree = 0.1 | |
thirdNum, _, _ := apd.NewFromString(viewInputThree) | |
var testAgainst float64 | |
testAgainst = 0.3 | |
against, _, _ := apd.NewFromString(".3") | |
otherAgainst := apd.New(3, -1) // 3 * (10^-1) | |
var testSum float64 | |
testSum = testNumOne + testNumTwo + testNumThree | |
sum := apd.New(0, 0) // 0 * (0 ^ 10) | |
ctx := apd.BaseContext.WithPrecision(32) // 32 digits of precision for this calculation context | |
ctx.Add(sum, firstNum, secondNum) // Has return values that specify errors as well as conditions | |
ctx.Add(sum, sum, thirdNum) | |
cmpTestOne := against.Cmp(sum) | |
cmpTestTwo := otherAgainst.Cmp(sum) | |
fmt.Printf("(float64) .1 + .1 + .1 === .3: %t\n", (testSum == testAgainst)) // false | |
fmt.Printf("(apd.Decimal) \".1\" + \".1\" + \".1\" == \".3\": %t\n", (cmpTestOne == 0)) // true | |
fmt.Printf("(apd.Decimal) \".1\" + \".1\" + \".1\" == (3 * (10^-1)): %t\n", (cmpTestTwo == 0)) // true | |
fmt.Printf("(float64) sum (compiler cuts off zeros where precision is lost): %f\n", testSum) | |
fmt.Printf("(apd.Decimal) sum: %s\n", sum.String()) | |
percent := apd.New(1, 2) // could also be (100,0) | |
ctx.Mul(percent, percent, sum) // Has return values that specify errors as well as conditions | |
fmt.Printf("Percentages: %s -> %s%%\n", sum, percent.Text('f')) //Text('f') formats in non-exp form (not explicitly needed here) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment