# Fixed point decimals for accounting

**URL:** <https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400>\
**Category:** General Usage\
**Created:** [June 22, 2021, 9:55pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400 "2021-06-22T21:55:29Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [June 22, 2021, 9:55pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/1 "2021-06-22T21:55:29Z")

</div>

What are some efficient ways to implement fixed point decimals, for tasks like accounting?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [June 22, 2021, 10:08pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/2 "2021-06-22T22:08:27Z")

</div>

[https://juliahub.com/ui/Search?q=decimal&type=packages](https://juliahub.com/ui/Search?q=decimal&type=packages)

Both [Decimals.jl](https://juliahub.com/ui/Packages/Decimals/04Vnf/0.4.1) and [DecFP.jl](https://juliahub.com/ui/Packages/DecFP/QmCKT/1.1.0) look quite good.

Alternatively, you could just do all computations in integer cents and divide by 100 for display.

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [June 22, 2021, 10:11pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/3 "2021-06-22T22:11:41Z")

</div>

ok thanks, I found fixedpointdecimal.jl looked really good. But, the output is not just a number, but also a description.

I thought of dividing integers, but that means inputting values multiplied by 100, and also could create problems when weighting.

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [June 22, 2021, 10:16pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/4 "2021-06-22T22:16:45Z")

</div>

I wasn’t sure from the documentation for Decimals.jl or DecFP.jl, to actually fix the decimals, when numbers are manipulate.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 22, 2021, 10:28pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/5 "2021-06-22T22:28:00Z")

</div>

> [@brett\_knoss](#):
>
> I wasn’t sure from the documentation for Decimals.jl or DecFP.jl, to actually fix the decimals, when numbers are manipulate.

That’s because they are floating-point decimal types. Why do you need fixed point specifically, as opposed to decimal floating-point?

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [June 22, 2021, 10:29pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/6 "2021-06-22T22:29:22Z")

</div>

Yes, exactly.

---

<div class="post-metadata">

**Author:** ![Impressium](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/impressium/32/19575_2.png) [@Impressium](https://discourse.julialang.org/u/Impressium)\
**Post date:** [June 23, 2021, 5:41am UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/7 "2021-06-23T05:41:42Z")

</div>

> **[GitHub - JuliaMath/FixedPointDecimals.jl: Julia fixed-point decimals built...](https://github.com/JuliaMath/FixedPointDecimals.jl)**
>
> Julia fixed-point decimals built from integers. Contribute to JuliaMath/FixedPointDecimals.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [June 23, 2021, 6:25am UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/8 "2021-06-23T06:25:41Z")

</div>

```julia
struct AccountingNumber <: Real
    x::Int

    AccountingNumber(x::Number) = new(round(Int, 100*x))
end

Base.show(io::IO, x::AccountingNumber) = Printf.@printf(io, "%.2f", x.x/100)
...

```

Add some conversion and promotion methods and you should be home.

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [June 23, 2021, 4:28pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/9 "2021-06-23T16:28:06Z")

</div>

> [@gustaphe](#):
>
> `Base.show(io::IO, x::AccountingNumber) = Printf.@printf(io, "%.2f", x.x/100)`

But what if I have a number like 1.999999, it would round to 2.00 and not 1.99

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [June 23, 2021, 4:33pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/10 "2021-06-23T16:33:04Z")

</div>

Correctly, I would have thought. Is the accounting standard to round down? In that case, replace `round` in the constructor by `floor`.

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [June 23, 2021, 4:36pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/11 "2021-06-23T16:36:39Z")

</div>

OK, that would work. Usually, there is only 2 decimals, there are cases, of 1/10th cent, there normal rules apply. The problem is that I’m not rounding, and the values need to balance exactly.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [June 23, 2021, 4:44pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/12 "2021-06-23T16:44:19Z")

</div>

You could have

```julia
struct AccountingNumber
x::Int
nofdecimals::Int

AccountingNumber(x, nofdecimals=2) = new(floor(Int, x.x*exp10(nofdecimals)), nofdecimals)
end

```

Might be a bit overkill for those mills though.

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [June 23, 2021, 5:22pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/13 "2021-06-23T17:22:00Z")

</div>

> [@gustaphe](#):
>
> ```julia
> struct AccountingNumber
> x::Int
> nofdecimals::Int
> 
> AccountingNumber(x, nofdecimals=2) = new(floor(Int, x.x*exp10(nofdecimals)), nofdecimals)
> end
> 
> ```

I think I have an idea of things to play with. How do I call a struct?

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [June 23, 2021, 5:38pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/14 "2021-06-23T17:38:29Z")

</div>

If it has the constructor i suggested above, then `n = AccountingNumber(6.24)` will create an `AccountingNumber` representing `6.24` (by way of the fields `x=624; nofdecimals=2`). Is that what you mean by “call a struct”?

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [June 23, 2021, 5:45pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/15 "2021-06-23T17:45:03Z")

</div>

Yes, I thing it is. But;

```julia
struct AccountingNumber
	x::Int
	nofdecimals::Int

	AccountingNumber(x, nofdecimals=2) = new(floor(Int, x.x*exp10(nofdecimals)), nofdecimals)
end

n=AccountingNumber(6.25)

```

gives an error;

```julia
Type Float64 has no field x

```

Why is there no field?

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [June 23, 2021, 5:49pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/16 "2021-06-23T17:49:42Z")

</div>

My bad, the constructor should have `x`, not `x.x`. As an argument to the constructor it’s a normal number, so it doesn’t have any fields.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 23, 2021, 6:14pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/17 "2021-06-23T18:14:27Z")

</div>

> [@gustaphe](#):
>
> Add some conversion and promotion methods and you should be home.

It seems like you are re-inventing the wheel here…

(I really don’t understand why you wouldn’t just use decimal floating point.)

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [June 23, 2021, 6:36pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/18 "2021-06-23T18:36:49Z")

</div>

If your goal is to _use_ the numbers for accounting I agree. But if you want to figure out _how to implement_ the numbers (which is how I read the question), that’s its own challenge and this is how I’d start solving it.

It might make sense to make a specific type for this (even with decimal numbers), since apparently the rounding rules in accounting are funky.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 23, 2021, 6:46pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/19 "2021-06-23T18:46:37Z")

</div>

> [@gustaphe](#):
>
> If your goal is to _use_ the numbers for accounting I agree. But if you want to figure out _how to implement_ the numbers (which is how I read the question), that’s its own challenge and this is how I’d start solving it.

There are multiple fixed-point and decimal-float packages; why not look at them?

> It might make sense to make a specific type for this (even with decimal numbers), since apparently the rounding rules in accounting are funky.

Decimal floating-point supports multiple rounding modes already, and will typically accumulate errors (in a long sequence of calculations) much more slowly than fixed point.

But the OP hasn’t clearly defined their application or their requirements, so we are just guessing here. That’s part of why I keep asking to find out what specifically is wrong (if anything) with decimal floating point for their application.

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [June 23, 2021, 9:14pm UTC](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400/20 "2021-06-23T21:14:48Z")

</div>

I’ve looked at several, and this is much the same. I’m thinking floor would be useful here, if each term had 3 or more decimals. I’ll see if there is a way to concact 0. It might not be an issue to just use floats, but the problem, is that I’m worried that some of the tests won’t work right, if the difference between certain values is not exactly 0. I could make a MWE to illustrate this better.

[Next page](https://discourse.julialang.org/t/fixed-point-decimals-for-accounting/63400.md?page=2)
