But in that case, and especially in that case, in any system that might interact with, say, a UI where a field is in decimal USD, Stripe needs to be careful about which things are price_decimal and price_zerodecimal. Unless you have a near-religious fervor that all variables not annotated with _decimal are assumed to be _zerodecimal, in such a situation one might go so far as to auto-reject any PR that does not suffix all variables explicitly. Because the alternative is hard-to-detect 100x-off bugs that occur when battle-tested systems/libraries are reused in different contexts.
Most currencies do not have "Cent" as a base unit. And there are currencies without a smaller base unit, most notably japanese Yen.
The problem is, that there exists no established currency neutral name to distinguish between the two possible units that coincide in such cases as Yen.
I was thinking about the following:
class AmountOfMoney
property int FinerAmount
property decimal CoarserAmount
In the case of Yen (FinerAmount == CoarserAmount) is always true.Any suggestions for better wordings?
class AmountOfMoney
int mantissa
int exponent # base 10If we have for example USD 10.42, the values in my implementation are:
FinerAmount = 1042
CoarserAmount = 10.42
The profile of the class was abbreviated. Of course, we also need a currency property for the general case: Currency = USDollar
The definition of the class for the currency in pseudo-code: class Iso4217CurrencyCode
int NumericCode
string AlphabeticCode
int DecimalPlaces
static USDollar = new Iso4217CurrencyCode(840, "USD", 2);
static Yen = new Iso4217CurrencyCode(392, "JPY", 0);
The constructor for the amount of money only uses FinerAmount, and CoarserAmount is calculated: CoarserAmount => Convert.ToDecimal(FinerAmount / Math.Pow(10, Currency.DecimalPlaces));
So foo = AmountOfMoney(FinerAmount: 1042, Currency: USDollar);
sets foo.CoarserAmount automatically to 10.42.But
bar = AmountOfMoney(FinerAmount: 1042, Currency: Yen);
sets bar.CoarserAmount automatically to 1042.