{-|
Module : Numeric.Decimal
Description : General arbitrary-precision decimal floating-point number type
Copyright : © 2016 Robert Leslie
License : BSD3
Maintainer : rob@mars.org
Stability : experimental
This module provides a general-purpose 'Number' type supporting decimal
arithmetic for both limited precision floating-point (IEEE 754-2008) and for
arbitrary precision floating-point (following the same principles as IEEE 754
and IEEE 854-1987) as described in the
<http://speleotrove.com/decimal/ General Decimal Arithmetic Specification>
by Mike Cowlishaw. In addition to floating-point arithmetic, integer and
unrounded floating-point arithmetic are included as subsets.
Unlike the binary floating-point types 'Float' and 'Double', the 'Number' type
can represent and perform arithmetic with decimal numbers exactly.
Internally, a 'Number' is represented with an integral coefficient and base-10
exponent.
The 'Number' type supports lossless conversion to and from a string
representation via the 'Show' and 'Read' instances. Note that there may be
multiple representations of values that are numerically equal (e.g. 1 and
1.00) which are preserved by this conversion.
-}
module Numeric.Decimal
( -- * Usage
-- $usage
-- * Arbitrary-precision decimal numbers
Number
, BasicDecimal
, ExtendedDecimal
, GeneralDecimal
-- ** Precision types
, module Numeric.Decimal.Precision
-- ** Rounding types
, Rounding
, RoundHalfUp
, RoundHalfEven
, RoundHalfDown
, RoundCeiling
, RoundFloor
, RoundUp
, Round05Up
, RoundDown
-- * Functions
, cast
) where
import Numeric.Decimal.Number
import Numeric.Decimal.Precision
import Numeric.Decimal.Rounding
-- | A basic decimal floating point number with 9 digits of precision, rounding half up
type BasicDecimal = Number P9 RoundHalfUp
-- | A decimal floating point number with selectable precision, rounding half even
type ExtendedDecimal p = Number p RoundHalfEven
-- | A decimal floating point number with infinite precision
type GeneralDecimal = ExtendedDecimal PInfinite
basicDefaultContext :: TrapHandler P9 RoundHalfUp -> Context P9 RoundHalfUp
basicDefaultContext handler = defaultContext { trapHandler = trap }
where trap Inexact = id
trap Rounded = id
trap Subnormal = id
trap sig = handler sig
extendedDefaultContext :: Context p RoundHalfEven
extendedDefaultContext = defaultContext
-- $usage
--
-- It is recommended that you create an alias for the type of numbers you wish
-- to support in your application. For example:
--
-- > type Decimal = BasicDecimal
--
-- This is a basic number type with 9 decimal digits of precision that rounds
-- half up.
--
-- > type Decimal = ExtendedDecimal P19
--
-- This is a number type with 19 decimal digits of precision that rounds half
-- even.
--
-- > type Decimal = GeneralDecimal
--
-- This is a number type with infinite precision. (Note that not all
-- operations support numbers with infinite precision.)
--
-- It is also possible to use a decimal number type in a @default@
-- declaration, possibly replacing 'Double' or 'Integer'. For example:
--
-- > default (Integer, Decimal)