The way I’d go about this would probably be to build a package on top of Unitful.jl that would let you handle numbers with a unit of dollars, or cents, or 1/16th of a cent, or whatever you prefer.
Not only would that ensure correct rounding, but it would also prevent coding errors, such as adding a number of euros to a number of dollars without first applying an exchange rate.
I’ll have to look into that. I don’t need conversion for what I’m doing, but I was thinking of making a package, and there it would be useful. It could also be useful for inventory, and accrual accounting.
For basic accounting in all countries that use a decimal currency, such as Dollars and Cents, all numbers are always two decimal places.
This is mostly —but not generally— true; some of the Gulf states (Bahrain, for example: 1 dinar =1000 fils) use three decimal places in their currencies.
As mentioned already, DecFP.jl is probably the way to go, as this uses Intel’s Decimal Floating-Point Library which is intended for legally-regulated financial arithmetic. Disclaimer: I don’t know the details of what you’re trying to do or the legal regulations and jurisdiction in which you’re operating; it’s up to you to check what applies in your case(s).
Umm… pretty sure they’d be fine with 20 or at most 30. The entire GDP is only 10^13 or so. Even the net market value of all assets is probably only 10^3 times that big (the US is less than 300 years old).
Umm… pretty sure they’d be fine with 20 or at most 30. The entire GDP is only 10^13 or so. Even the net market value of all assets is probably only 10^3 times that big (the US is less than 300 years old).
But what if you want to model the economy of USA , 1000 years into the future? With hyperinflation… when they start coming for your GOLD.
If you want to model things then binary floats are fine, and you can nondimensionalize the problem with all dollars as a fraction of GDP. It’s only if you want to record legal transactions that you need decimal floats
You enter all your values into DFP types and do your arithmetic using DFP
julia> using DFPs
julia> DFP_setDefaultPrecision(200)
200
julia> a = DFP("1.23"); b= DFP("23.456"); c= a * b + a;
julia> DFP_toCommonString(c)
"30.080880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
julia> c_rounded = round(c,digits=2); # rounded to the nearest cent
julia> DFP_toCommonString(c_rounded)
"30.080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
You can find the source for DFPs module version 1.2.6 here. You have to go to the website and manually copy the source code, it is not in a repository. Don’t worry it is all in a single file called DFPs.jl
I put my modules in my path this way. Then I put a symbolic link inside the mymodules directory to the actual location of the module file.
I think I can test how to use DecFP, but I want to make sure everything. I didn’t see any other documentation like tutorials? This might help some rounding problems, but I’m not finding a way to actually round.
That’s because DecFP uses exactly the same functions as those in Julia’s standard library, once you’ve constructed a DecFP number. This is part of the beauty of multiple dispatch—the package just adds methods to the existing functions to handle the new type. Here, you call the round function:
julia> using DecFP
julia> x = d"15.3412" # constructs a 64-bit decimal float, representing 15.3412 exactly
15.3412
julia> round(x, digits=2)
15.34
julia> typeof(ans)
Dec64
Note that it implements “banker’s rounding” (i.e., round-to-even) by default, although there are other rounding modes available:
Yes this appars to work, it doesn’t seem to display 2 digits, but that’s not a big issue. If I save to to PostgresSQL and load the DBs into Libre Office, then I could probably set Calc to two digits, then it would be good all the time.
I am not sure why you expect it to do that, it is a generic decimal floating point library. If you round before printing, it should work fine, also AFAICT with printf, eg