This basically also shows you why you should always use integers for currencies! This means in practice you should use at least a 64 bit number but they may not be enough in case of hyper-inflation so probably they use larger numbers (128bit, 256 bit), or of variable length in professional and scientific economy programs (and currency/math libraries).
Code: Select all
; Use integer values (quad) to express currency values (most basic way)
Procedure.q GetCurrencyValue(NominalFull.q,NominalCentile)
CurrencyValue.q = (NominalFull* 100) + NominalCentile
ProcedureReturn CurrencyValue
EndProcedure
Procedure GetCurrencyCentile(Value.q)
ProcedureReturn Value % 100
EndProcedure
Procedure.s StrCurrency(Value.q)
Protected result$
Protected rest
If Value>=0
result$="+"
EndIf
rest = value % 100
result$ = result$ + Str(Value/100) + "," + RSet(Str(Abs(rest)),2,"0")
ProcedureReturn result$
EndProcedure
Debug StrCurrency(123499)+ " EUR"
Debug StrCurrency(-495)+ " USD"
Debug "LIMIT:"
Debug " " + $7FFFFFFFFFFFFFFF +" quad integer value"
Debug StrCurrency($7FFFFFFFFFFFFFFF)+" CAN$"
Debug FormatNumber($7FFFFFFFFFFFFFFF/100) + " float/double precision error" ; precision/accuracy is limited
Now you see why you should only use integers for currency calculations. And because of the limitations that also will arise with 64bit quads, the possibility that centiles are too big (some currencies and petrol prices have thousands of a currency unit, or 1/4th and 1/2th kind of sub-units) - all that causes the necessity for a well thought-through concept of a currency data type when you create an application or database, and want to make conversions. Imagine that, there are countries were a loaf of bread may coast millions or billions of currency units, because of hyper-inflation, so this goes into exotic long numbers with variable length maybe... IMO that's pretty interesting. I wonder what they use in MS for the data type I believe it's a 128 bit integer and they use millis, plus there must be an indicator word or long for the currency type (euro, dollar etc.), the resulting structure or data-type would be at least around 18-20 bytes (compared to the 8 a quad would take). But one could imagine very dynamic types with variable sizes. For example the first byte may indicate how many bytes are needed to express the currency units, and the second how many bytes for the millis or centis (and what kind they are either millis or centies etc.)
Code: Select all
Structure MySuperCurrencyStructure
CurrencyID.l ; Could be a readable FourCC or three letters with null termination i.e. "EUR" or "USD"
Value.q[2] ; 128 bit big number (must be used with a special math library)
; perhaps in tenthousands of a unit 0..9999 . One cent = 100 tenthousands :)
EndStructure
But this is only an idea. The fractions of the unit may be also very important for example when the main unit increases a lot in value (e.g. through deflation), and fractions of it become more of interest and fine granulated, as is the case with bitcoin or so (?). So finding the perfect technique for currency management for ANY case from scratch, if it's of importance to you, might become very tricky and adventurous
