# tinybike/Decimals.jl

Pure Julia decimal arithmetic library.
Julia
Latest commit d7303df Dec 14, 2016 committed on GitHub Merge pull request #14 from femtotrader/patch-1
`Run Travis CI build with Julia 0.5 and nightly build`
 Failed to load latest commit information. src test .gitignore .travis.yml LICENSE README.md REQUIRE

## 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.3.

### 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 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");
``````

``````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"
``````

``````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
``````

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

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

`is` only returns true between two equivalent Decimal objects:

``````julia> is(x, decimal("0.2"))
true

julia> is(x, 0.2)
false
``````

Rounding:

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

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

### Tests

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

``````\$ julia test/runtests.jl
``````