decimal-arithmetic-0.2.0.0: An implementation of Mike Cowlishaw's General Decimal Arithmetic Specification

Copyright© 2016 Robert Leslie
LicenseBSD3
Maintainerrob@mars.org
Stabilityexperimental
Safe HaskellTrustworthy
LanguageHaskell2010

Numeric.Decimal

Contents

Description

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 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, decimal number types can perform decimal arithmetic exactly. Internally, decimal numbers are represented with an integral coefficient and base-10 exponent.

>>> 29.99 + 4.71 :: Double
34.699999999999996
>>> 29.99 + 4.71 :: BasicDecimal
34.70
>>> 0.1 + 0.2 == (0.3 :: Double)
False
>>> 0.1 + 0.2 == (0.3 :: BasicDecimal)
True

Decimal numbers support lossless conversion to and from a string representation via 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.

Synopsis

Usage

You should choose a decimal number type with appropriate precision and rounding to use in your application. There are several options:

  • BasicDecimal is a number type with 9 decimal digits of precision that rounds half up.
  • ExtendedDecimal is a number type constructor with selectable precision that rounds half even. For example, ExtendedDecimal P34 is a number type with 34 decimal digits of precision. There is a range of ready-made precisions available, including P1 through P50 on up to P2000 (the IEEE 754 smallest and basic formats correspond to precisions P7, P16, or P34). Alternatively, an arbitrary precision can be constructed through type application of PPlus1 and/or PTimes2 to any existing precision.
  • GeneralDecimal is a number type with infinite precision. Note that not all operations support numbers with infinite precision.
  • The most versatile Decimal type constructor is parameterized by both a precision and a rounding algorithm. For example, Decimal P20 RoundDown is a number type with 20 decimal digits of precision that rounds down (truncates). Several Rounding algorithms are available to choose from.

It is suggested to create an alias for the type of numbers you wish to support in your application. For example:

type Number = ExtendedDecimal P16

A decimal number type may be used in a default declaration, possibly replacing Double and/or Integer. For example:

default (Integer, BasicDecimal)

Advanced usage

Additional operations and control beyond what is provided by the basic numeric type classes are available through the use of Numeric.Decimal.Arithmetic and Numeric.Decimal.Operation.

Arbitrary-precision decimal numbers

data Decimal p r Source #

A decimal floating point number with selectable precision and rounding algorithm

Instances

(Precision p, Rounding r) => Enum (Decimal p r) Source # 

Methods

succ :: Decimal p r -> Decimal p r #

pred :: Decimal p r -> Decimal p r #

toEnum :: Int -> Decimal p r #

fromEnum :: Decimal p r -> Int #

enumFrom :: Decimal p r -> [Decimal p r] #

enumFromThen :: Decimal p r -> Decimal p r -> [Decimal p r] #

enumFromTo :: Decimal p r -> Decimal p r -> [Decimal p r] #

enumFromThenTo :: Decimal p r -> Decimal p r -> Decimal p r -> [Decimal p r] #

Eq (Decimal p r) Source # 

Methods

(==) :: Decimal p r -> Decimal p r -> Bool #

(/=) :: Decimal p r -> Decimal p r -> Bool #

(FinitePrecision p, Rounding r) => Floating (Decimal p r) Source # 

Methods

pi :: Decimal p r #

exp :: Decimal p r -> Decimal p r #

log :: Decimal p r -> Decimal p r #

sqrt :: Decimal p r -> Decimal p r #

(**) :: Decimal p r -> Decimal p r -> Decimal p r #

logBase :: Decimal p r -> Decimal p r -> Decimal p r #

sin :: Decimal p r -> Decimal p r #

cos :: Decimal p r -> Decimal p r #

tan :: Decimal p r -> Decimal p r #

asin :: Decimal p r -> Decimal p r #

acos :: Decimal p r -> Decimal p r #

atan :: Decimal p r -> Decimal p r #

sinh :: Decimal p r -> Decimal p r #

cosh :: Decimal p r -> Decimal p r #

tanh :: Decimal p r -> Decimal p r #

asinh :: Decimal p r -> Decimal p r #

acosh :: Decimal p r -> Decimal p r #

atanh :: Decimal p r -> Decimal p r #

log1p :: Decimal p r -> Decimal p r #

expm1 :: Decimal p r -> Decimal p r #

log1pexp :: Decimal p r -> Decimal p r #

log1mexp :: Decimal p r -> Decimal p r #

(FinitePrecision p, Rounding r) => Fractional (Decimal p r) Source # 

Methods

(/) :: Decimal p r -> Decimal p r -> Decimal p r #

recip :: Decimal p r -> Decimal p r #

fromRational :: Rational -> Decimal p r #

(Precision p, Rounding r) => Num (Decimal p r) Source # 

Methods

(+) :: Decimal p r -> Decimal p r -> Decimal p r #

(-) :: Decimal p r -> Decimal p r -> Decimal p r #

(*) :: Decimal p r -> Decimal p r -> Decimal p r #

negate :: Decimal p r -> Decimal p r #

abs :: Decimal p r -> Decimal p r #

signum :: Decimal p r -> Decimal p r #

fromInteger :: Integer -> Decimal p r #

(Precision p, Rounding r) => Ord (Decimal p r) Source # 

Methods

compare :: Decimal p r -> Decimal p r -> Ordering #

(<) :: Decimal p r -> Decimal p r -> Bool #

(<=) :: Decimal p r -> Decimal p r -> Bool #

(>) :: Decimal p r -> Decimal p r -> Bool #

(>=) :: Decimal p r -> Decimal p r -> Bool #

max :: Decimal p r -> Decimal p r -> Decimal p r #

min :: Decimal p r -> Decimal p r -> Decimal p r #

(Precision p, Rounding r) => Read (Decimal p r) Source # 
(Precision p, Rounding r) => Real (Decimal p r) Source # 

Methods

toRational :: Decimal p r -> Rational #

(FinitePrecision p, Rounding r) => RealFloat (Decimal p r) Source # 
(FinitePrecision p, Rounding r) => RealFrac (Decimal p r) Source # 

Methods

properFraction :: Integral b => Decimal p r -> (b, Decimal p r) #

truncate :: Integral b => Decimal p r -> b #

round :: Integral b => Decimal p r -> b #

ceiling :: Integral b => Decimal p r -> b #

floor :: Integral b => Decimal p r -> b #

Show (Decimal p r) Source # 

Methods

showsPrec :: Int -> Decimal p r -> ShowS #

show :: Decimal p r -> String #

showList :: [Decimal p r] -> ShowS #

Precision p => Precision (Decimal p r) Source # 

Methods

precision :: Decimal p r -> Maybe Int Source #

type BasicDecimal = Decimal P9 RoundHalfUp Source #

A decimal floating point number with 9 digits of precision, rounding half up

type ExtendedDecimal p = Decimal p RoundHalfEven Source #

A decimal floating point number with selectable precision, rounding half even

type GeneralDecimal = ExtendedDecimal PInfinite Source #

A decimal floating point number with infinite precision

Precision types

class Precision p where Source #

Precision indicates the maximum number of significant decimal digits a number may have.

Minimal complete definition

precision

Methods

precision :: p -> Maybe Int Source #

Return the precision of the argument, or Nothing if the precision is infinite.

class Precision p => FinitePrecision p Source #

A subclass of precisions that are finite

data P1 Source #

A precision of 1 significant digit

type P2 = PPlus1 P1 Source #

A precision of 2 significant digits

type P3 = PPlus1 P2 Source #

A precision of 3 significant digits

type P4 = PTimes2 P2 Source #

Et cetera

type PPlus1 p Source #

Arguments

 = PPlus p P1

A precision of (p + 1) significant digits

type PPlus2 p Source #

Arguments

 = PPlus p P2

A precision of (p + 2) significant digits

type PPlus3 p Source #

Arguments

 = PPlus p P3

A precision of (p + 3) significant digits

type PPlus4 p Source #

Arguments

 = PPlus p P4

A precision of (p + 4) significant digits

type PPlus5 p Source #

Arguments

 = PPlus p P5

A precision of (p + 5) significant digits

type PPlus6 p Source #

Arguments

 = PPlus p P6

A precision of (p + 6) significant digits

type PPlus7 p Source #

Arguments

 = PPlus p P7

A precision of (p + 7) significant digits

type PPlus8 p Source #

Arguments

 = PPlus p P8

A precision of (p + 8) significant digits

type PPlus9 p Source #

Arguments

 = PPlus p P9

A precision of (p + 9) significant digits

type PTimes2 = PTimes P2 Source #

type PTimes10 = PTimes P10 Source #

data PInfinite Source #

A precision of unlimited significant digits

Rounding types

class Rounding r Source #

A rounding algorithm to use when the result of an arithmetic operation exceeds the precision of the result type

Minimal complete definition

rounding, round

data RoundHalfUp Source #

If the discarded digits represent greater than or equal to half (0.5) of the value of a one in the next left position then the value is rounded up. If they represent less than half, the value is rounded down.

data RoundHalfEven Source #

If the discarded digits represent greater than half (0.5) of the value of a one in the next left position then the value is rounded up. If they represent less than half, the value is rounded down. If they represent exactly half, the value is rounded to make its rightmost digit even.

data RoundHalfDown Source #

If the discarded digits represent greater than half (0.5) of the value of a one in the next left position then the value is rounded up. If they represent less than half or exactly half, the value is rounded down.

data RoundCeiling Source #

Round toward +∞

data RoundFloor Source #

Round toward −∞

Instances

data RoundUp Source #

Round away from 0

Instances

Rounding RoundUp Source # 

Methods

rounding :: RoundUp -> RoundingAlgorithm

round :: Precision p => Decimal p RoundUp -> Arith p RoundUp (Decimal p RoundUp)

data Round05Up Source #

Round zero or five away from 0

Instances

data RoundDown Source #

Round toward 0 (truncate)

Instances

Functions

cast :: (Precision p, Rounding r) => Decimal a b -> Decimal p r Source #

Cast a Decimal to another precision and/or rounding algorithm, immediately rounding if necessary to the new precision using the new algorithm.

toBool :: Decimal p r -> Bool Source #

Return False if the argument is zero or NaN, and True otherwise.