-- 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.5.0.0 -- | 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 mode 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 mode 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, and rounding half even -- (IEEE 754 §4.3.3). extendedDefaultContext :: Context p RoundHalfEven -- | A decimal arithmetic monad parameterized by the precision p -- and rounding mode 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 -- mode. 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.Classes.Eq Numeric.Decimal.Arithmetic.Signals 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.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 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) -- | This module implements the decimal interchange format encodings -- described in IEEE 754-2008, including the decimal32, -- decimal64, and decimal128 formats, as well as arbitrary -- width decimal{k} formats through the use of Format with -- KPlus32 and/or KTimes2. For example, to use a -- decimal96 format: -- --
--   type Decimal96 = ExtendedDecimal (Format (KPlus32 K64) DecimalCoefficient)
--   
-- -- Currently only a decimal encoding of coefficients is implemented, but -- a binary encoding may be added in the future. module Numeric.Decimal.Encoding -- | A decimal floating point number with 7 digits of precision, rounding -- half even, and a 32-bit encoded representation using the -- decimal32 interchange format (with a decimal encoding for the -- coefficient) type Decimal32 = ExtendedDecimal Pdecimal32 -- | A decimal floating point number with 16 digits of precision, rounding -- half even, and a 64-bit encoded representation using the -- decimal64 interchange format (with a decimal encoding for the -- coefficient) type Decimal64 = ExtendedDecimal Pdecimal64 -- | A decimal floating point number with 34 digits of precision, rounding -- half even, and a 128-bit encoded representation using the -- decimal128 interchange format (with a decimal encoding for the -- coefficient) type Decimal128 = ExtendedDecimal Pdecimal128 -- | A type with Precision instance specifying decimal32 -- interchange format parameters (using a decimal encoding for the -- coefficient) having an effective precision of 7 decimal digits type Pdecimal32 = Format K32 DecimalCoefficient -- | A type with Precision instance specifying decimal64 -- interchange format parameters (using a decimal encoding for the -- coefficient) having an effective precision of 16 decimal digits type Pdecimal64 = Format K64 DecimalCoefficient -- | A type with Precision instance specifying decimal128 -- interchange format parameters (using a decimal encoding for the -- coefficient) having an effective precision of 34 decimal digits type Pdecimal128 = Format K128 DecimalCoefficient -- | A type (with a Precision instance) for specifying interchange -- format parameters k and coefficient encoding c data Format k c -- | Interchange format parameters used to define an encoding and derive -- the format's precision and Emax class Parameters k -- | Parameters for the decimal32 interchange format data K32 -- | Parameters for the decimal64 interchange format type K64 = KPlus32 K32 -- | Parameters for the decimal128 interchange format type K128 = KTimes2 K64 -- | Parameters for a decimal{k + 32} interchange format data KPlus32 k -- | Parameters for a decimal{k × 2} interchange format data KTimes2 k -- | Specify a decimal encoding for the coefficient. data DecimalCoefficient -- | Specify a binary encoding for the coefficient (currently -- unimplemented). data BinaryCoefficient instance Numeric.Decimal.Encoding.Parameters Numeric.Decimal.Encoding.K32 instance Numeric.Decimal.Encoding.Parameters k => Numeric.Decimal.Encoding.Parameters (Numeric.Decimal.Encoding.KPlus32 k) instance Numeric.Decimal.Encoding.Parameters k => Numeric.Decimal.Encoding.Parameters (Numeric.Decimal.Encoding.KTimes2 k) instance Numeric.Decimal.Encoding.CoefficientEncoding Numeric.Decimal.Encoding.DecimalCoefficient instance Numeric.Decimal.Encoding.CoefficientEncoding Numeric.Decimal.Encoding.BinaryCoefficient instance Numeric.Decimal.Encoding.Parameters k => Numeric.Decimal.Precision.Precision (Numeric.Decimal.Encoding.Format k c) instance Numeric.Decimal.Encoding.Parameters k => Numeric.Decimal.Precision.FinitePrecision (Numeric.Decimal.Encoding.Format k c) instance Numeric.Decimal.Encoding.Parameters k => Data.Binary.Class.Binary (Numeric.Decimal.Number.Decimal (Numeric.Decimal.Encoding.Format k Numeric.Decimal.Encoding.DecimalCoefficient) r) -- | 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 -- | 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) -- | 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) -- | 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) -- | 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 as stated -- below. -- -- The following rules apply: -- -- power :: (FinitePrecision p, Rounding r) => Decimal a b -> Decimal c d -> 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 RoundHalfEven 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) -- | 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) -- | 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: -- -- exp :: FinitePrecision p => Decimal a b -> Arith p r (Decimal p RoundHalfEven) -- | 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: -- -- 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: -- -- log10 :: FinitePrecision p => Decimal a b -> Arith p r (Decimal p RoundHalfEven) -- | 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) -- | 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) -- | 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) -- | 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 Right -- LT if the first is less than the second, Right -- EQ if they are equal, or Right GT -- if the first is greater than the second. -- -- A Left value is returned if the result is NaN, indicating an -- “unordered” comparison (see IEEE 754 §5.11). compare :: Decimal a b -> Decimal c d -> Arith p r (Either (Decimal p r) Ordering) -- | 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 :: Decimal a b -> Decimal c d -> Arith p r (Either (Decimal p r) Ordering) -- | 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 :: Decimal a b -> Decimal a b -> Arith p r (Decimal a b) -- | 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 :: 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 :: 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 :: Decimal a b -> Decimal a b -> Arith p r (Decimal a b) -- | roundToIntegralValue takes one operand. It is identical to the -- roundToIntegralExact operation except that the Inexact -- and Rounded flags are never set even if the operand is rounded -- (that is, the operation is quiet unless the operand is a signaling -- NaN). roundToIntegralValue :: (Precision a, Rounding r) => Decimal a b -> Arith p r (Decimal a r) -- | roundToIntegralExact takes one operand. If the operand is a -- special value, or the exponent of the operand is non-negative, -- then the result is the same as the operand (unless the operand is a -- signaling NaN, as usual). -- -- Otherwise (the operand has a negative exponent) the result is the same -- as using the quantize operation using the given operand as the -- left-hand-operand, 1E+0 as the right-hand-operand, and the precision -- of the operand as the precision setting. The rounding mode is -- taken from the context, as usual. roundToIntegralExact :: (Precision a, Rounding r) => Decimal a b -> Arith p r (Decimal a 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 a b -> Decimal c d -> 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) -- | 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) -- | 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) -- | 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) -- | 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) -- | 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 InvalidOperation (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) -- | 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 InvalidOperation (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) -- | isZero takes one operand. The result is True if the -- operand is a zero; otherwise it is False. This operation is -- unaffected by context and is quiet — no flags are changed in -- the context. isZero :: Decimal a b -> Arith p r Bool -- | isSigned takes one operand. The result is True if the -- sign of the operand is 1; otherwise it is False. This -- operation is unaffected by context and is quiet — no flags are -- changed in the context. isSigned :: Decimal a b -> Arith p r Bool -- | isFinite takes one operand. The result is True 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 False. 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 True if the -- operand is an Infinity; otherwise it is False. This operation -- is unaffected by context and is quiet — no flags are changed in -- the context. isInfinite :: Decimal a b -> Arith p r Bool -- | isNormal takes one operand. The result is True if the -- operand is a positive or negative normal number; otherwise it -- is False. This operation is quiet; no flags are changed -- in the context. isNormal :: Precision a => Decimal a b -> Arith p r Bool -- | isSubnormal takes one operand. The result is True if the -- operand is a positive or negative subnormal number; otherwise -- it is False. This operation is quiet; no flags are -- changed in the context. isSubnormal :: Precision a => Decimal a b -> Arith p r Bool -- | isNaN takes one operand. The result is True if the -- operand is a NaN (quiet or signaling); otherwise it is False. -- This operation is unaffected by context and is quiet — no flags -- are changed in the context. isNaN :: Decimal a b -> Arith p r Bool -- | isQNaN takes one operand. The result is True if the -- operand is a quiet NaN; otherwise it is False. This operation -- is unaffected by context and is quiet — no flags are changed in -- the context. isQNaN :: Decimal a b -> Arith p r Bool -- | isSNaN takes one operand. The result is True if the -- operand is a signaling NaN; otherwise it is False. This -- operation is unaffected by context and is quiet — no flags are -- changed in the context. isSNaN :: Decimal a b -> Arith p r Bool -- | isCanonical takes one operand. The result is True if the -- operand is canonical; otherwise it is False. 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 True. This operation is -- unaffected by context and is quiet — no flags are changed in -- the context. isCanonical :: Decimal a b -> Arith p r Bool -- | compareTotal takes two operands and compares them using their -- abstract representation rather than their numerical value. A total -- ordering is defined for all possible abstract representations, as -- described below. If the first operand is lower in the total order than -- the second operand then the result is LT, if the operands have -- the same abstract representation then the result is EQ, and if -- the first operand is higher in the total order than the second operand -- then the result is GT. The total ordering is defined as -- follows. -- --
    --
  1. The following items describe the ordering for representations -- whose sign is 0. If the sign is 1, the order is -- reversed. A representation with a sign of 1 is always lower in -- the ordering than one with a sign of 0.
  2. --
  3. Numbers (representations which are not NaNs) are ordered such that -- a larger numerical value is higher in the ordering. If two -- representations have the same numerical value then the exponent is -- taken into account; larger (more positive) exponents are higher in the -- ordering.
  4. --
  5. All quiet NaNs are higher in the total ordering than all signaling -- NaNs.
  6. --
  7. Quiet NaNs and signaling NaNs are ordered according to their -- payload; a larger payload is higher in the ordering.
  8. --
-- -- For example, the following values are ordered from lowest to highest: -- -NaN -sNaN -Infinity -127 -1 -1.00 -0 -0.000 0 1.2300 1.23 1E+9 -- Infinity sNaN NaN NaN456. compareTotal :: Decimal a b -> Decimal c d -> Arith p r Ordering -- | compareTotalMagnitude takes two operands and compares them -- using their abstract representation rather than their numerical value -- and with their sign ignored and assumed to be 0. The result is -- identical to that obtained by using compareTotal on two -- operands which are the copyAbs copies of the operands to -- compareTotalMagnitude. compareTotalMagnitude :: Decimal a b -> Decimal c d -> Arith p r Ordering -- | 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 -- | Quiet NaN QuietClass :: NaNClass -- | Signaling NaN SignalingClass :: NaNClass -- | 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) -- | scaleb takes two operands. If either operand is a NaN then the -- general arithmetic rules apply. Otherwise, the second operand must be -- a finite integer with an exponent of zero and in the range ±2 × -- (Emax + precision) inclusive, where Emax is the -- largest value that can be returned by the logb operation at the -- same precision setting. (If is is not, the Invalid Operation -- condition is raised and the result is NaN.) -- -- If the first operand is infinite then that Infinity is returned, -- otherwise the result is the first operand modified by adding the value -- of the second operand to its exponent. The result may Overflow -- or Underflow. scaleb :: Decimal a b -> Decimal c d -> Arith p r (Decimal a b) -- | sameQuantum takes two operands, and returns True if the -- two operands have the same exponent or False otherwise. -- The result is never affected by either the sign or the coefficient of -- either operand. -- -- If either operand is a special value, True 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 -- | 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) -- | 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) -- | 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) -- | 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) instance GHC.Classes.Eq Numeric.Decimal.Operation.Class instance GHC.Enum.Enum Numeric.Decimal.Operation.NaNClass 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. -- -- Some decimal numbers also support encoding and decoding specific IEEE -- 754 interchange formats via a Binary instance. 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 -- | A decimal floating point number with 7 digits of precision, rounding -- half even, and a 32-bit encoded representation using the -- decimal32 interchange format (with a decimal encoding for the -- coefficient) type Decimal32 = ExtendedDecimal Pdecimal32 -- | A decimal floating point number with 16 digits of precision, rounding -- half even, and a 64-bit encoded representation using the -- decimal64 interchange format (with a decimal encoding for the -- coefficient) type Decimal64 = ExtendedDecimal Pdecimal64 -- | A decimal floating point number with 34 digits of precision, rounding -- half even, and a 128-bit encoded representation using the -- decimal128 interchange format (with a decimal encoding for the -- coefficient) type Decimal128 = ExtendedDecimal Pdecimal128 -- | Precision indicates the maximum number of significant decimal digits a -- number may have. class Precision p where eMax n = subtract 1 . (10 ^) . numDigits <$> base where mlength = precision n :: Maybe Int base = (10 *) . fromIntegral <$> mlength :: Maybe Coefficient eMin = fmap (1 -) . eMax -- | 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 type with Precision instance specifying decimal32 -- interchange format parameters (using a decimal encoding for the -- coefficient) having an effective precision of 7 decimal digits type Pdecimal32 = Format K32 DecimalCoefficient -- | A type with Precision instance specifying decimal64 -- interchange format parameters (using a decimal encoding for the -- coefficient) having an effective precision of 16 decimal digits type Pdecimal64 = Format K64 DecimalCoefficient -- | A type with Precision instance specifying decimal128 -- interchange format parameters (using a decimal encoding for the -- coefficient) having an effective precision of 34 decimal digits type Pdecimal128 = Format K128 DecimalCoefficient -- | 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 -- | Return 0 or 1 if the argument is False or -- True, respectively. This is basically an optimized -- toEnum . fromEnum and allows an all-decimal -- usage of the operations from Numeric.Decimal.Operation that -- return a Bool. fromBool :: Bool -> Decimal p r -- | Return -1, 0, or 1 if the argument is -- LT, EQ, or GT, respectively. This allows an -- all-decimal usage of the operations from -- Numeric.Decimal.Operation that return an Ordering. fromOrdering :: Ordering -> Decimal p r