-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | An implementation of the General Decimal Arithmetic
-- Specification
--
-- This package provides an implementation of the General Decimal
-- Arithmetic Specification by Mike Cowlishaw.
--
-- For details, see http://speleotrove.com/decimal/
@package decimal-arithmetic
@version 0.4.0.0
-- | The functions in this module implement conversions between
-- Decimal and String as described in the General
-- Decimal Arithmetic Specification.
--
-- Because these functions are also used to implement Show and
-- Read class methods, it is not usually necessary to import this
-- module except to use the toEngineeringString function.
module Numeric.Decimal.Conversion
-- | Convert a number to a string, using scientific notation if an exponent
-- is needed.
toScientificString :: Decimal p r -> ShowS
-- | Convert a number to a string, using engineering notation if an
-- exponent is needed.
toEngineeringString :: Decimal p r -> ShowS
-- | Convert a string to a number, as defined by its abstract
-- representation. The string is expected to conform to the numeric
-- string syntax described here.
toNumber :: ReadP (Decimal PInfinite r)
-- | It is not usually necessary to import this module unless you want to
-- use the arithmetic operations from Numeric.Decimal.Operation or
-- you need precise control over the handling of exceptional conditions
-- in an arithmetic computation.
module Numeric.Decimal.Arithmetic
-- | A context for decimal arithmetic, carrying signal flags, trap enabler
-- state, and a trap handler, parameterized by precision p and
-- rounding algorithm r
data Context p r
-- | Return a new context with all signal flags cleared and all traps
-- disabled.
newContext :: Context p r
-- | The current signal flags of the context
flags :: Context p r -> Signals
-- | Return the precision of the arithmetic context (or Nothing if
-- the precision is infinite).
getPrecision :: Precision p => Arith p r (Maybe Int)
-- | Return the rounding algorithm of the arithmetic context.
getRounding :: Rounding r => Arith p r RoundingAlgorithm
-- | A value representation of a rounding algorithm (cf. Rounding).
data RoundingAlgorithm
RoundDown :: RoundingAlgorithm
RoundHalfUp :: RoundingAlgorithm
RoundHalfEven :: RoundingAlgorithm
RoundCeiling :: RoundingAlgorithm
RoundFloor :: RoundingAlgorithm
RoundHalfDown :: RoundingAlgorithm
RoundUp :: RoundingAlgorithm
Round05Up :: RoundingAlgorithm
-- | Return a new context with all signal flags cleared, all traps enabled
-- except for Inexact, Rounded, and Subnormal, using
-- a precision of 9 significant decimal digits, and rounding half up.
-- Trapped signals simply call throwError with the corresponding
-- Exception, and can be caught using catchError.
basicDefaultContext :: Context P9 RoundHalfUp
-- | Return a new context with all signal flags cleared, all traps disabled
-- (IEEE 854 §7), using selectable precision (the IEEE 754 smallest and
-- basic formats correspond to precisions P7, P16, or
-- P34), and rounding half even (IEEE 754 §4.3.3).
extendedDefaultContext :: Context p RoundHalfEven
-- | A decimal arithmetic monad parameterized by the precision p
-- and rounding algorithm r
data Arith p r a
-- | Evaluate an arithmetic computation in the given context and return the
-- final value (or exception) and resulting context.
runArith :: Arith p r a -> Context p r -> (Either (Exception p r) a, Context p r)
-- | Evaluate an arithmetic computation in the given context and return the
-- final value or exception, discarding the resulting context.
evalArith :: Arith p r a -> Context p r -> Either (Exception p r) a
-- | Perform a subcomputation using a different precision and/or rounding
-- algorithm. The subcomputation is evaluated within a new context with
-- all flags cleared and all traps disabled. Any flags set in the context
-- of the subcomputation are ignored, but if an exception is returned it
-- will be re-raised within the current context.
subArith :: Arith a b (Decimal a b) -> Arith p r (Decimal a b)
-- | A representation of an exceptional condition
data Exception p r
-- | The signal raised by the exceptional condition
exceptionSignal :: Exception p r -> Signal
-- | The defined result for the exceptional condition
exceptionResult :: Exception p r -> Decimal p r
data Signal
-- | Raised when the exponent of a result has been altered or constrained
-- in order to fit the constraints of a specific concrete representation
Clamped :: Signal
-- | Raised when a non-zero dividend is divided by zero
DivisionByZero :: Signal
-- | Raised when a result is not exact (one or more non-zero coefficient
-- digits were discarded during rounding)
Inexact :: Signal
-- | Raised when a result would be undefined or impossible
InvalidOperation :: Signal
-- | Raised when the exponent of a result is too large to be represented
Overflow :: Signal
-- | Raised when a result has been rounded (that is, some zero or non-zero
-- coefficient digits were discarded)
Rounded :: Signal
-- | Raised when a result is subnormal (its adjusted exponent is less than
-- Emin), before any rounding
Subnormal :: Signal
-- | Raised when a result is both subnormal and inexact
Underflow :: Signal
-- | A group of signals can be manipulated as a set.
data Signals
-- | Create a set of signals from a singleton.
signal :: Signal -> Signals
-- | Create a set of signals from a list.
signals :: [Signal] -> Signals
-- | A set containing every signal
allSignals :: Signals
-- | Determine whether a signal is a member of a set.
signalMember :: Signal -> Signals -> Bool
-- | Set the given signal flag in the context of the current arithmetic
-- computation, and call the trap handler if the trap for this signal is
-- currently enabled.
raiseSignal :: Signal -> Decimal p r -> Arith p r (Decimal p r)
-- | Clear the given signal flags from the context of the current
-- arithmetic computation.
clearFlags :: Signals -> Arith p r ()
-- | A trap handler function may return a substitute result for the
-- operation that caused the exceptional condition, or it may call
-- throwError to pass control to an enclosing catchError
-- handler (or abort the arithmetic computation).
type TrapHandler p r = Exception p r -> Arith p r (Decimal p r)
-- | Evaluate an arithmetic computation within a modified context that
-- enables the given signals to be trapped by the given handler. The
-- previous trap handler (and enabler state) will be restored during any
-- trap, as well as upon completion. Any existing trap handlers for
-- signals not mentioned remain in effect.
trap :: Signals -> TrapHandler p r -> Arith p r a -> Arith p r a
instance GHC.Show.Show (Numeric.Decimal.Arithmetic.Exception p r)
instance GHC.Show.Show Numeric.Decimal.Arithmetic.Signal
instance GHC.Enum.Bounded Numeric.Decimal.Arithmetic.Signal
instance GHC.Enum.Enum Numeric.Decimal.Arithmetic.Signal
instance GHC.Classes.Eq Numeric.Decimal.Arithmetic.Signal
instance GHC.Classes.Eq Numeric.Decimal.Arithmetic.Signals
instance GHC.Base.Functor (Numeric.Decimal.Arithmetic.Arith p r)
instance GHC.Base.Applicative (Numeric.Decimal.Arithmetic.Arith p r)
instance GHC.Base.Monad (Numeric.Decimal.Arithmetic.Arith p r)
instance Control.Monad.Error.Class.MonadError (Numeric.Decimal.Arithmetic.Exception p r) (Numeric.Decimal.Arithmetic.Arith p r)
instance Control.Monad.State.Class.MonadState (Numeric.Decimal.Arithmetic.Context p r) (Numeric.Decimal.Arithmetic.Arith p r)
instance GHC.Show.Show Numeric.Decimal.Arithmetic.Signals
instance GHC.Base.Monoid Numeric.Decimal.Arithmetic.Signals
-- | The operations described in the General Decimal Arithmetic
-- Specification are provided here.
--
-- It is suggested to import this module qualified to avoid
-- Prelude name clashes:
--
--
-- import qualified Numeric.Decimal.Operation as Op
--
--
-- Note that it is not usually necessary to import this module unless you
-- want to use operations unavailable through class methods, or you need
-- precise control over the handling of exceptional conditions. (See also
-- Numeric.Decimal.Arithmetic.)
module Numeric.Decimal.Operation
-- | abs takes one operand. If the operand is negative, the result
-- is the same as using the minus operation on the operand.
-- Otherwise, the result is the same as using the plus operation
-- on the operand.
--
-- Note that the result of this operation is affected by context and may
-- set flags. The copyAbs operation may be used if this is
-- not desired.
abs :: (Precision p, Rounding r) => Decimal a b -> Arith p r (Decimal p r)
-- | add takes two operands. If either operand is a special
-- value then the general rules apply.
--
-- Otherwise, the operands are added.
--
-- The result is then rounded to precision digits if necessary,
-- counting from the most significant digit of the result.
add :: (Precision p, Rounding r) => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | subtract takes two operands. If either operand is a special
-- value then the general rules apply.
--
-- Otherwise, the operands are added after inverting the sign used
-- for the second operand.
--
-- The result is then rounded to precision digits if necessary,
-- counting from the most significant digit of the result.
subtract :: (Precision p, Rounding r) => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | compare takes two operands and compares their values
-- numerically. If either operand is a special value then the
-- general rules apply. No flags are set unless an operand is a signaling
-- NaN.
--
-- Otherwise, the operands are compared, returning −1 if the
-- first is less than the second, 0 if they are equal, or
-- 1 if the first is greater than the second.
compare :: (Precision p, Rounding r) => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | compareSignal takes two operands and compares their values
-- numerically. This operation is identical to compare, except
-- that if neither operand is a signaling NaN then any quiet NaN operand
-- is treated as though it were a signaling NaN. (That is, all NaNs
-- signal, with signaling NaNs taking precedence over quiet NaNs.)
compareSignal :: (Precision p, Rounding r) => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | divide takes two operands. If either operand is a special
-- value then the general rules apply.
--
-- Otherwise, if the divisor is zero then either the Division undefined
-- condition is raised (if the dividend is zero) and the result is NaN,
-- or the Division by zero condition is raised and the result is an
-- Infinity with a sign which is the exclusive or of the signs of the
-- operands.
--
-- Otherwise, a “long division” is effected.
--
-- The result is then rounded to precision digits, if necessary,
-- according to the rounding algorithm and taking into account the
-- remainder from the division.
divide :: (FinitePrecision p, Rounding r) => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | exp takes one operand. If the operand is a NaN then the general
-- rules for special values apply.
--
-- Otherwise, the result is e raised to the power of the operand,
-- with the following cases:
--
--
-- - If the operand is −Infinity, the result is 0 and exact.
-- - If the operand is a zero, the result is 1 and exact.
-- - If the operand is +Infinity, the result is +Infinity and
-- exact.
-- - Otherwise the result is inexact and will be rounded using the
-- round-half-even algorithm. The coefficient will have exactly
-- precision digits (unless the result is subnormal). These
-- inexact results should be correctly rounded, but may be up to 1 ulp
-- (unit in last place) in error.
--
exp :: FinitePrecision p => Decimal a b -> Arith p r (Decimal p RoundHalfEven)
-- | fusedMultiplyAdd takes three operands; the first two are
-- multiplied together, using multiply, with sufficient precision
-- and exponent range that the result is exact and unrounded. No
-- flags are set by the multiplication unless one of the first two
-- operands is a signaling NaN or one is a zero and the other is an
-- infinity.
--
-- Unless the multiplication failed, the third operand is then added to
-- the result of that multiplication, using add, under the current
-- context.
--
-- In other words, fusedMultiplyAdd x y z delivers a result
-- which is (x × y) + z with only the one, final, rounding.
fusedMultiplyAdd :: (Precision p, Rounding r) => Decimal a b -> Decimal c d -> Decimal e f -> Arith p r (Decimal p r)
-- | ln takes one operand. If the operand is a NaN then the general
-- rules for special values apply.
--
-- Otherwise, the operand must be a zero or positive, and the result is
-- the natural (base e) logarithm of the operand, with the
-- following cases:
--
--
-- - If the operand is a zero, the result is −Infinity and exact.
-- - If the operand is +Infinity, the result is +Infinity and
-- exact.
-- - If the operand equals one, the result is 0 and exact.
-- - Otherwise the result is inexact and will be rounded using the
-- round-half-even algorithm. The coefficient will have exactly
-- precision digits (unless the result is subnormal). These
-- inexact results should be correctly rounded, but may be up to 1 ulp
-- (unit in last place) in error.
--
ln :: FinitePrecision p => Decimal a b -> Arith p r (Decimal p RoundHalfEven)
-- | log10 takes one operand. If the operand is a NaN then the
-- general rules for special values apply.
--
-- Otherwise, the operand must be a zero or positive, and the result is
-- the base 10 logarithm of the operand, with the following cases:
--
--
-- - If the operand is a zero, the result is −Infinity and exact.
-- - If the operand is +Infinity, the result is +Infinity and
-- exact.
-- - If the operand equals an integral power of ten (including 10^0 and
-- negative powers) and there is sufficient precision to hold the
-- integral part of the result, the result is an integer (with an
-- exponent of 0) and exact.
-- - Otherwise the result is inexact and will be rounded using the
-- round-half-even algorithm. The coefficient will have exactly
-- precision digits (unless the result is subnormal). These
-- inexact results should be correctly rounded, but may be up to 1 ulp
-- (unit in last place) in error.
--
log10 :: FinitePrecision p => Decimal a b -> Arith p r (Decimal p RoundHalfEven)
-- | max takes two operands, compares their values numerically, and
-- returns the maximum. If either operand is a NaN then the general rules
-- apply, unless one is a quiet NaN and the other is numeric, in which
-- case the numeric operand is returned.
max :: (Precision p, Rounding r) => Decimal a b -> Decimal a b -> Arith p r (Decimal a b)
-- | maxMagnitude takes two operands and compares their values
-- numerically with their sign ignored and assumed to be 0.
--
-- If, without signs, the first operand is the larger then the original
-- first operand is returned (that is, with the original sign). If,
-- without signs, the second operand is the larger then the original
-- second operand is returned. Otherwise the result is the same as from
-- the max operation.
maxMagnitude :: (Precision p, Rounding r) => Decimal a b -> Decimal a b -> Arith p r (Decimal a b)
-- | min takes two operands, compares their values numerically, and
-- returns the minimum. If either operand is a NaN then the general rules
-- apply, unless one is a quiet NaN and the other is numeric, in which
-- case the numeric operand is returned.
min :: (Precision p, Rounding r) => Decimal a b -> Decimal a b -> Arith p r (Decimal a b)
-- | minMagnitude takes two operands and compares their values
-- numerically with their sign ignored and assumed to be 0.
--
-- If, without signs, the first operand is the smaller then the original
-- first operand is returned (that is, with the original sign). If,
-- without signs, the second operand is the smaller then the original
-- second operand is returned. Otherwise the result is the same as from
-- the min operation.
minMagnitude :: (Precision p, Rounding r) => Decimal a b -> Decimal a b -> Arith p r (Decimal a b)
-- | minus takes one operand, and corresponds to the prefix minus
-- operator in programming languages.
--
-- Note that the result of this operation is affected by context and may
-- set flags. The copyNegate operation may be used instead
-- of minus if this is not desired.
minus :: (Precision p, Rounding r) => Decimal a b -> Arith p r (Decimal p r)
-- | plus takes one operand, and corresponds to the prefix plus
-- operator in programming languages.
--
-- Note that the result of this operation is affected by context and may
-- set flags.
plus :: (Precision p, Rounding r) => Decimal a b -> Arith p r (Decimal p r)
-- | multiply takes two operands. If either operand is a special
-- value then the general rules apply. Otherwise, the operands are
-- multiplied together (“long multiplication”), resulting in a number
-- which may be as long as the sum of the lengths of the two operands.
--
-- The result is then rounded to precision digits if necessary,
-- counting from the most significant digit of the result.
multiply :: (Precision p, Rounding r) => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | power takes two operands, and raises a number (the left-hand
-- operand) to a power (the right-hand operand). If either operand is a
-- special value then the general rules apply, except in certain
-- cases.
power :: (FinitePrecision p, Rounding r) => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | quantize takes two operands. If either operand is a special
-- value then the general rules apply, except that if either operand
-- is infinite and the other is finite an Invalid operation condition is
-- raised and the result is NaN, or if both are infinite then the result
-- is the first operand.
--
-- Otherwise (both operands are finite), quantize returns the
-- number which is equal in value (except for any rounding) and sign to
-- the first (left-hand) operand and which has an exponent set to
-- be equal to the exponent of the second (right-hand) operand.
--
-- The coefficient of the result is derived from that of the
-- left-hand operand. It may be rounded using the current rounding
-- setting (if the exponent is being increased), multiplied by a
-- positive power of ten (if the exponent is being decreased), or
-- is unchanged (if the exponent is already equal to that of the
-- right-hand operand).
--
-- Unlike other operations, if the length of the coefficient after
-- the quantize operation would be greater than precision then an
-- Invalid operation condition is raised. This guarantees that, unless
-- there is an error condition, the exponent of the result of a
-- quantize is always equal to that of the right-hand operand.
--
-- Also unlike other operations, quantize will never raise Underflow,
-- even if the result is subnormal and inexact.
quantize :: (Precision p, Rounding r) => Decimal p r -> Decimal a b -> Arith p r (Decimal p r)
-- | reduce takes one operand. It has the same semantics as the
-- plus operation, except that if the final result is finite it is
-- reduced to its simplest form, with all trailing zeros removed and its
-- sign preserved.
reduce :: (Precision p, Rounding r) => Decimal a b -> Arith p r (Decimal p r)
-- | squareRoot takes one operand. If the operand is a special
-- value then the general rules apply.
--
-- Otherwise, the ideal exponent of the result is defined to be half the
-- exponent of the operand (rounded to an integer, towards −Infinity, if
-- necessary) and then:
--
-- If the operand is less than zero an Invalid operation condition is
-- raised.
--
-- If the operand is greater than zero, the result is the square root of
-- the operand. If no rounding is necessary (the exact result requires
-- precision digits or fewer) then the coefficient and exponent
-- giving the correct value and with the exponent closest to the ideal
-- exponent is used. If the result must be inexact, it is rounded using
-- the round-half-even algorithm and the coefficient will have
-- exactly precision digits (unless the result is subnormal), and
-- the exponent will be set to maintain the correct value.
--
-- Otherwise (the operand is equal to zero), the result will be the zero
-- with the same sign as the operand and with the ideal exponent.
squareRoot :: FinitePrecision p => Decimal a b -> Arith p r (Decimal p RoundHalfEven)
-- | and is a logical operation which takes two logical operands.
-- The result is the digit-wise and of the two operands; each
-- digit of the result is the logical and of the corresponding digits of
-- the operands, aligned at the least-significant digit. A result digit
-- is 1 if both of the corresponding operand digits are 1; otherwise it
-- is 0.
and :: Precision p => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | canonical takes one operand. The result has the same value as
-- the operand but always uses a canonical encoding. The
-- definition of canonical is implementation-defined; if more than
-- one internal encoding for a given NaN, Infinity, or finite number is
-- possible then one “preferred” encoding is deemed canonical. This
-- operation then returns the value using that preferred encoding.
--
-- If all possible operands have just one internal encoding each, then
-- canonical always returns the operand unchanged (that is, it has
-- the same effect as copy). This operation is unaffected by
-- context and is quiet — no flags are changed in the context.
canonical :: Decimal a b -> Arith p r (Decimal a b)
-- | class_ takes one operand. The result is an indication of the
-- class of the operand, where the class is one of ten
-- possibilities, corresponding to one of the strings "sNaN"
-- (signaling NaN), "NaN" (quiet NaN), "-Infinity"
-- (negative infinity), "-Normal" (negative normal finite
-- number), "-Subnormal" (negative subnormal finite number),
-- "-Zero" (negative zero), "+Zero" (non-negative
-- zero), "+Subnormal" (positive subnormal finite number),
-- "+Normal" (positive normal finite number), or
-- "+Infinity" (positive infinity). This operation is quiet; no
-- flags are changed in the context.
--
-- Note that unlike the special values in the model, the sign of any NaN
-- is ignored in the classification, as required by IEEE 754.
class_ :: Precision a => Decimal a b -> Arith p r Class
data Class
-- | Number (finite or infinite)
NumberClass :: Sign -> NumberClass -> Class
-- | Not a number (quiet or signaling)
NaNClass :: NaNClass -> Class
data Sign
-- | Positive or non-negative
Pos :: Sign
-- | Negative
Neg :: Sign
data NumberClass
-- | Zero
ZeroClass :: NumberClass
-- | Subnormal finite number
SubnormalClass :: NumberClass
-- | Normal finite number
NormalClass :: NumberClass
-- | Infinity
InfinityClass :: NumberClass
data NaNClass
-- | Not a number (quiet)
QNaNClass :: NaNClass
-- | Not a number (signaling)
SNaNClass :: NaNClass
-- | copy takes one operand. The result is a copy of the operand.
-- This operation is unaffected by context and is quiet — no flags
-- are changed in the context.
copy :: Decimal a b -> Arith p r (Decimal a b)
-- | copyAbs takes one operand. The result is a copy of the operand
-- with the sign set to 0. Unlike the abs operation, this
-- operation is unaffected by context and is quiet — no flags are
-- changed in the context.
copyAbs :: Decimal a b -> Arith p r (Decimal a b)
-- | copyNegate takes one operand. The result is a copy of the
-- operand with the sign inverted (a sign of 0 becomes 1
-- and vice versa). Unlike the minus operation, this operation is
-- unaffected by context and is quiet — no flags are changed in
-- the context.
copyNegate :: Decimal a b -> Arith p r (Decimal a b)
-- | copySign takes two operands. The result is a copy of the first
-- operand with the sign set to be the same as the sign of
-- the second operand. This operation is unaffected by context and is
-- quiet — no flags are changed in the context.
copySign :: Decimal a b -> Decimal c d -> Arith p r (Decimal a b)
-- | invert is a logical operation which takes one logical operand.
-- The result is the digit-wise inversion of the operand; each
-- digit of the result is the inverse of the corresponding digit of the
-- operand. A result digit is 1 if the corresponding operand digit is 0;
-- otherwise it is 0.
invert :: FinitePrecision p => Decimal a b -> Arith p r (Decimal p r)
-- | isCanonical takes one operand. The result is 1 if the operand
-- is canonical; otherwise it is 0. The definition of
-- canonical is implementation-defined; if more than one internal
-- encoding for a given NaN, Infinity, or finite number is possible then
-- one “preferred” encoding is deemed canonical. This operation then
-- tests whether the internal encoding is that preferred encoding.
--
-- If all possible operands have just one internal encoding each, then
-- isCanonical always returns 1. This operation is unaffected by
-- context and is quiet — no flags are changed in the context.
isCanonical :: Decimal a b -> Arith p r Bool
-- | isFinite takes one operand. The result is 1 if the operand is
-- neither infinite nor a NaN (that is, it is a normal number, a
-- subnormal number, or a zero); otherwise it is 0. This operation is
-- unaffected by context and is quiet — no flags are changed in
-- the context.
isFinite :: Decimal a b -> Arith p r Bool
-- | isInfinite takes one operand. The result is 1 if the operand is
-- an Infinity; otherwise it is 0. This operation is unaffected by
-- context and is quiet — no flags are changed in the context.
isInfinite :: Decimal a b -> Arith p r Bool
-- | isNaN takes one operand. The result is 1 if the operand is a
-- NaN (quiet or signaling); otherwise it is 0. This operation is
-- unaffected by context and is quiet — no flags are changed in
-- the context.
isNaN :: Decimal a b -> Arith p r Bool
-- | isNormal takes one operand. The result is 1 if the operand is a
-- positive or negative normal number; otherwise it is 0. This
-- operation is quiet; no flags are changed in the context.
isNormal :: Precision a => Decimal a b -> Arith p r Bool
-- | isQNaN takes one operand. The result is 1 if the operand is a
-- quiet NaN; otherwise it is 0. This operation is unaffected by context
-- and is quiet — no flags are changed in the context.
isQNaN :: Decimal a b -> Arith p r Bool
-- | isSigned takes one operand. The result is 1 if the sign
-- of the operand is 1; otherwise it is 0. This operation is unaffected
-- by context and is quiet — no flags are changed in the context.
isSigned :: Decimal a b -> Arith p r Bool
-- | isSNaN takes one operand. The result is 1 if the operand is a
-- signaling NaN; otherwise it is 0. This operation is unaffected by
-- context and is quiet — no flags are changed in the context.
isSNaN :: Decimal a b -> Arith p r Bool
-- | isSubnormal takes one operand. The result is 1 if the operand
-- is a positive or negative subnormal number; otherwise it is 0.
-- This operation is quiet; no flags are changed in the context.
isSubnormal :: Precision a => Decimal a b -> Arith p r Bool
-- | isZero takes one operand. The result is 1 if the operand is a
-- zero; otherwise it is 0. This operation is unaffected by context and
-- is quiet — no flags are changed in the context.
isZero :: Decimal a b -> Arith p r Bool
-- | logb takes one operand. If the operand is a NaN then the
-- general arithmetic rules apply. If the operand is infinite then
-- +Infinity is returned. If the operand is a zero, then −Infinity is
-- returned and the Division by zero exceptional condition is raised.
--
-- Otherwise, the result is the integer which is the exponent of the
-- magnitude of the most significant digit of the operand (as though the
-- operand were truncated to a single digit while maintaining the value
-- of that digit and without limiting the resulting exponent). All
-- results are exact unless an integer result does not fit in the
-- available precision.
logb :: (Precision p, Rounding r) => Decimal a b -> Arith p r (Decimal p r)
-- | or is a logical operation which takes two logical operands. The
-- result is the digit-wise inclusive or of the two operands; each
-- digit of the result is the logical or of the corresponding digits of
-- the operands, aligned at the least-significant digit. A result digit
-- is 1 if either or both of the corresponding operand digits is 1;
-- otherwise it is 0.
or :: Precision p => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | radix takes no operands. The result is the radix (base) in
-- which arithmetic is effected; for this specification the result will
-- have the value 10.
radix :: Precision p => Arith p r (Decimal p r)
-- | rotate takes two operands. The second operand must be an
-- integer (with an exponent of 0) in the range −precision
-- through precision. If the first operand is a NaN then the
-- general arithmetic rules apply, and if it is infinite then the result
-- is the Infinity unchanged.
--
-- Otherwise (the first operand is finite) the result has the same
-- sign and exponent as the first operand, and a
-- coefficient which is a rotated copy of the digits in the
-- coefficient of the first operand. The number of places of rotation is
-- taken from the absolute value of the second operand, with the rotation
-- being to the left if the second operand is positive or to the right
-- otherwise.
--
-- If the coefficient of the first operand has fewer than
-- precision digits, it is treated as though it were padded on the
-- left with zeros to length precision before the rotation.
-- Similarly, if the coefficient of the first operand has more than
-- precision digits, it is truncated on the left before use.
--
-- The only flag that might be set is invalid-operation
-- (set if the first operand is an sNaN or the second is not valid).
--
-- The shift operation can be used to shift rather than rotate a
-- coefficient.
rotate :: FinitePrecision p => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | sameQuantum takes two operands, and returns 1 if the two
-- operands have the same exponent or 0 otherwise. The result is
-- never affected by either the sign or the coefficient of either
-- operand.
--
-- If either operand is a special value, 1 is returned only if
-- both operands are NaNs or both are infinities.
--
-- sameQuantum does not change any flags in the context.
sameQuantum :: Decimal a b -> Decimal c d -> Arith p r Bool
-- | shift takes two operands. The second operand must be an integer
-- (with an exponent of 0) in the range −precision through
-- precision. If the first operand is a NaN then the general
-- arithmetic rules apply, and if it is infinite then the result is the
-- Infinity unchanged.
--
-- Otherwise (the first operand is finite) the result has the same
-- sign and exponent as the first operand, and a
-- coefficient which is a shifted copy of the digits in the
-- coefficient of the first operand. The number of places to shift is
-- taken from the absolute value of the second operand, with the shift
-- being to the left if the second operand is positive or to the right
-- otherwise. Digits shifted into the coefficient are zeros.
--
-- The only flag that might be set is invalid-operation
-- (set if the first operand is an sNaN or the second is not valid).
--
-- The rotate operation can be used to rotate rather than shift a
-- coefficient.
shift :: Precision p => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | xor is a logical operation which takes two logical operands.
-- The result is the digit-wise exclusive or of the two operands;
-- each digit of the result is the logical exclusive-or of the
-- corresponding digits of the operands, aligned at the least-significant
-- digit. A result digit is 1 if one of the corresponding operand digits
-- is 1 and the other is 0; otherwise it is 0.
xor :: Precision p => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
instance GHC.Classes.Eq Numeric.Decimal.Operation.Class
instance GHC.Classes.Eq Numeric.Decimal.Operation.NaNClass
instance GHC.Classes.Eq Numeric.Decimal.Operation.NumberClass
instance GHC.Show.Show Numeric.Decimal.Operation.Class
-- | 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.
module Numeric.Decimal
-- | A decimal floating point number with selectable precision and rounding
-- algorithm
data Decimal p r
-- | A decimal floating point number with 9 digits of precision, rounding
-- half up
type BasicDecimal = Decimal P9 RoundHalfUp
-- | A decimal floating point number with selectable precision, rounding
-- half even
type ExtendedDecimal p = Decimal p RoundHalfEven
-- | A decimal floating point number with infinite precision
type GeneralDecimal = ExtendedDecimal PInfinite
-- | Precision indicates the maximum number of significant decimal digits a
-- number may have.
class Precision p
-- | Return the precision of the argument, or Nothing if the
-- precision is infinite.
precision :: Precision p => p -> Maybe Int
-- | A subclass of precisions that are finite
class Precision p => FinitePrecision p
-- | A precision of 1 significant digit
data P1
-- | A precision of 2 significant digits
type P2 = PTimes2 P1
-- | A precision of 3 significant digits
type P3 = PPlus1 P2
-- | Et cetera
type P4 = PTimes2 P2
type P5 = PPlus1 P4
type P6 = PTimes2 P3
type P7 = PPlus1 P6
type P8 = PTimes2 P4
type P9 = PPlus1 P8
type P10 = PTimes2 P5
type P11 = PPlus1 P10
type P12 = PTimes2 P6
type P13 = PPlus1 P12
type P14 = PTimes2 P7
type P15 = PPlus1 P14
type P16 = PTimes2 P8
type P17 = PPlus1 P16
type P18 = PTimes2 P9
type P19 = PPlus1 P18
type P20 = PTimes2 P10
type P21 = PPlus1 P20
type P22 = PTimes2 P11
type P23 = PPlus1 P22
type P24 = PTimes2 P12
type P25 = PPlus1 P24
type P26 = PTimes2 P13
type P27 = PPlus1 P26
type P28 = PTimes2 P14
type P29 = PPlus1 P28
type P30 = PTimes2 P15
type P31 = PPlus1 P30
type P32 = PTimes2 P16
type P33 = PPlus1 P32
type P34 = PTimes2 P17
type P35 = PPlus1 P34
type P36 = PTimes2 P18
type P37 = PPlus1 P36
type P38 = PTimes2 P19
type P39 = PPlus1 P38
type P40 = PTimes2 P20
type P41 = PPlus1 P40
type P42 = PTimes2 P21
type P43 = PPlus1 P42
type P44 = PTimes2 P22
type P45 = PPlus1 P44
type P46 = PTimes2 P23
type P47 = PPlus1 P46
type P48 = PTimes2 P24
type P49 = PPlus1 P48
type P50 = PTimes2 P25
type P75 = PPlus1 P74
type P100 = PTimes2 P50
type P150 = PTimes2 P75
type P200 = PTimes2 P100
type P250 = PTimes2 P125
type P300 = PTimes2 P150
type P400 = PTimes2 P200
type P500 = PTimes2 P250
type P1000 = PTimes2 P500
type P2000 = PTimes2 P1000
-- | A precision of (p + 1) significant digits
data PPlus1 p
-- | A precision of (p × 2) significant digits
data PTimes2 p
-- | A precision of unlimited significant digits
data PInfinite
-- | A rounding algorithm to use when the result of an arithmetic operation
-- exceeds the precision of the result type
class Rounding r
-- | 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 result
-- coefficient should be incremented by 1 (rounded up). Otherwise the
-- discarded digits are ignored.
data RoundHalfUp
-- | If the discarded digits represent greater than half (0.5) the value of
-- a one in the next left position then the result coefficient should be
-- incremented by 1 (rounded up). If they represent less than half, then
-- the result coefficient is not adjusted (that is, the discarded digits
-- are ignored).
--
-- Otherwise (they represent exactly half) the result coefficient is
-- unaltered if its rightmost digit is even, or incremented by 1 (rounded
-- up) if its rightmost digit is odd (to make an even digit).
data RoundHalfEven
-- | If the discarded digits represent greater than half (0.5) of the value
-- of a one in the next left position then the result coefficient should
-- be incremented by 1 (rounded up). Otherwise (the discarded digits are
-- 0.5 or less) the discarded digits are ignored.
data RoundHalfDown
-- | (Round toward +∞.) If all of the discarded digits are zero or if the
-- sign is 1 the result is unchanged. Otherwise, the result
-- coefficient should be incremented by 1 (rounded up).
data RoundCeiling
-- | (Round toward −∞.) If all of the discarded digits are zero or if the
-- sign is 0 the result is unchanged. Otherwise, the sign is 1 and
-- the result coefficient should be incremented by 1.
data RoundFloor
-- | (Round away from 0.) If all of the discarded digits are zero the
-- result is unchanged. Otherwise, the result coefficient should be
-- incremented by 1 (rounded up).
data RoundUp
-- | (Round zero or five away from 0.) The same as RoundUp, except
-- that rounding up only occurs if the digit to be rounded up is 0 or 5,
-- and after overflow the result is the same as for RoundDown.
data Round05Up
-- | (Round toward 0; truncate.) The discarded digits are ignored; the
-- result is unchanged.
data RoundDown
-- | Cast a Decimal to another precision and/or rounding algorithm,
-- immediately rounding if necessary to the new precision using the new
-- algorithm.
cast :: (Precision p, Rounding r) => Decimal a b -> Decimal p r
-- | If the argument is False, return a Decimal value zero;
-- if True, return the value one. This is basically an optimized
-- toEnum . fromEnum to support an all-decimal usage of the
-- operations from Numeric.Decimal.Operation that return a
-- Bool.
fromBool :: Bool -> Decimal p r