# Two Decimal Place Fixed Point Decimals a Necessary Feature

For basic accounting in all countries that use a decimal currency, such as Dollars and Cents, all numbers are always two decimal places.

For this reason, having a financial number type, that is always two decimals, would be extremely valuable, and should be a built in feature.

Why? Perfectly fine, actively maintained packages exist already, eg

19 Likes

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.

3 Likes

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).

1 Like

Just use Decimal Floating Point with 200 decimal digits like this

``````julia> using DFPs
[ Info: Precompiling DFPs [top-level]

julia> DFP_setDefaultPrecision(200)
200

julia> a = DFP(Ď€); DFP_toCommonString(a)
"3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303820"

julia> b=a^a^a; DFP_toCommonString(b)
"1340164183006357435.2974491296401314150993749745734992377879275165860340926190940681482694726113011422734374889525974969490984456374683189320748144171329686859566550586183230440926034493572213761908396"

julia> c = DFP("0.01") + DFP("0.02"); DFP_toCommonString(c)
"0.030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
``````

You see 200 decimal digits in decimal floating point should be enough even for the Federal Reserve of USA.

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).

2 Likes

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

But it made me chuckle. thanks.

3 Likes

But I want to model it accurate down to the last cent.

I like doing stuff like this

``````julia> 666.66 ^ 777.77
Inf

julia> d = DFP("666.66") ^ DFP("777.77"); DFP_toCommonString(d)
"2.2290695290173413346892956756741292206624583124046169287860844720642750156423246050757086944529571798897824685796704570535219728601085970863260994593278212928618633515968324077642684223432198762330306E2196"

julia> DFP_toShortCommonString(d)
"2.22907E2196"
``````
1 Like

Currency exchange rates are listed on the Oslo BĂ¸rs with five decimal places. And I think Iâ€™ve seen accounting with 1/1000 Norwegian krone.

Do I do DPF() until Iâ€™m done arithmetic, then add a string to the DataFrame?

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.

``````\$ cd ~/.julia/

\$ cat config/startup.jl

\$ ls -l /Users/ssiew/.julia/mymodules/DFPs.jl
lrwxr-xr-x  1 ssiew  staff  36 18 Jul  2020 /Users/ssiew/.julia/mymodules/DFPs.jl -> /Users/ssiew/juliascript/DFP/DFPs.jl
``````
3 Likes

DFPs wonâ€™t load for me. Do I need to put in an address?

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:

``````julia> round(d"15.345", digits=2)
15.34

julia> round(d"15.355", digits=2)
15.36
``````
5 Likes

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

``````julia> @sprintf("%0.2f", d"123.456")
"123.46"
``````
2 Likes