# JuliaMath/Decimals.jl

Pure Julia decimal arithmetic library.
Julia
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
 Failed to load latest commit information. src Aug 5, 2018 test Jun 26, 2018 .gitignore Jul 6, 2014 .travis.yml Jun 26, 2018 LICENSE Jul 7, 2014 README.md Jun 26, 2018 REQUIRE Dec 11, 2017

## Decimals.jl

Basic routines for decimal arithmetic in Julia. Supports addition, subtraction, negation, multiplication, division, and equality operations; exponentiation coming as soon as I find the time to write it. This is a pure Julia implementation, so if you are concerned about pure speed, calling `libmpdec` functions directly is likely to be faster. Tested in Julia 0.6.

### Background

Why is this needed? Because floating point arithmetic does things like this:

``````julia> 0.1 + 0.2
0.30000000000000004
``````

Clearly, this is not okay for fields like finance, where it's important to be able to trust that \$0.30 is actually 30 cents, rather than 30.000000000000004 cents.

(For an in-depth explanation of the underlying problem - "ordinary" decimals like 0.1 and 0.2 are base-10 numbers, many of which do not have an exact representation in binary - check out the amusingly-named floating-point-gui.de.)

### Installation and use

``````julia> Pkg.add("Decimals")

julia> using Decimals
``````

#### The Decimal object

You can parse Decimal objects from strings:

``````julia> parse(Decimal, "0.2")
Decimals.Decimal(0,2,-1)

julia> parse(Decimal, "-2.5e6")
Decimals.Decimal(1,25,5)
``````

You can construct Decimal objects from other Real numbers:

``````julia> Decimal(0.1)
Decimal(0,1,-1)

julia> Decimal(-1003)
Decimals.Decimal(1, 1003, 0)
``````

Or can create Decimal objects from either strings or numbers using `decimal`:

``````julia> decimal("0.2")
Decimal(0,2,-1)

julia> decimal(0.1)
Decimal(0,1,-1)

julia> decimal("-2.5e6")
Decimal(1,25,5)
``````

To convert back to a string or a float:

``````julia> x = decimal("0.2");

julia> string(x)
"0.2"

julia> float(x)
0.2
``````

It is also possible to call the Decimal constructor directly, by specifying the sign (`s`), coefficient (`c`), and exponent (`q`):

``````julia> Decimal(1,2,-2)
``````

The numerical value of a Decimal is given by `(-1)^s * c * 10^q`. `s` must be 0 (positive) or 1 (negative). `c` must be non-negative; `c` and `q` must be integers.

#### Operations

``````julia> x, y = decimal("0.2"), decimal("0.1");
``````

Addition:

``````julia> string(x + y)
"0.3"
``````

Subtraction:

``````julia> string(x - y)
"0.1"
``````

Negation:

``````julia> string(-x)
"-0.2"
``````

Multiplication:

``````julia> string(x * y)
"0.02"
``````

Division:

``````julia> string(x / y)
"2"
``````

Inversion:

``````julia> string(inv(x))
"5"
``````

Broadcasting:

``````julia> [x y] .* 2
2-element Array{Decimal,1}:
Decimal(0,1,-1)
Decimal(0,5,-2)
``````

Equals (`==` and `isequal`):

``````julia> x == decimal("0.2")
true

julia> x != decimal("0.1")
true
``````

Inequality:

``````julia> x >= y
true

julia> isless(x, y)
false
``````

`==` returns true for Decimal vs. Number comparisons:

``````julia> x == 0.2
true
``````

Rounding:

``````julia> round(decimal(3.1415), digits=2)
Decimal(0,314,-2)

julia> string(ans)
"3.14"
``````

### Tests

Unit tests are in `test/`. To run the tests:

``````julia> Pkg.test("Decimals")
``````