| Safe Haskell | Safe |
|---|
Data.Deka.IO
Contents
Description
Floating-point decimals.
This uses the decNumber C library, so you will want to read the documentation about it to fully understand this module:
http://speleotrove.com/decimal/decnumber.html
http://speleotrove.com/decimal/decarith.html
http://speleotrove.com/decimal/
In particular, this module implements the decQuad type. decQuad supports up to 34 digits of precision and exponents up to (roughly) 6144. It doesn't silently round, overflow, or underflow; rather, the library will notify you if these things happen.
Every function in this module returns canonical Quad (contrast
the decNumber library which will, under limited circumstances,
return non-canonical decimals). I am not certain that canonical
vs. non-canonical matters in typical use, though it may matter
when using compareTotal.
Many functions in this module clash with Prelude names, so you might want to do
import qualified Data.Deka.Pure as D
- data Quad
- data Round
- roundCeiling :: Round
- roundUp :: Round
- roundHalfUp :: Round
- roundHalfEven :: Round
- roundHalfDown :: Round
- roundDown :: Round
- roundFloor :: Round
- round05Up :: Round
- roundMax :: Round
- data Flag
- divisionUndefined :: Flag
- divisionByZero :: Flag
- divisionImpossible :: Flag
- invalidOperation :: Flag
- inexact :: Flag
- invalidContext :: Flag
- underflow :: Flag
- overflow :: Flag
- conversionSyntax :: Flag
- data Flags
- setFlag :: Flag -> Flags -> Flags
- clearFlag :: Flag -> Flags -> Flags
- checkFlag :: Flag -> Flags -> Bool
- emptyFlags :: Flags
- flagList :: Flags -> [String]
- data Env a
- runEnvIO :: Env a -> IO a
- data Ctx a
- getStatus :: Ctx Flags
- setStatus :: Flags -> Ctx ()
- getRound :: Ctx Round
- setRound :: Round -> Ctx ()
- runCtxIO :: Ctx a -> IO (a, Flags)
- liftEnv :: Env a -> Ctx a
- data DecClass
- sNan :: DecClass
- qNan :: DecClass
- negInf :: DecClass
- negNormal :: DecClass
- negSubnormal :: DecClass
- negZero :: DecClass
- posZero :: DecClass
- posSubnormal :: DecClass
- posNormal :: DecClass
- posInf :: DecClass
- decClass :: Quad -> Env DecClass
- data Digit
- digitsToIntegral :: [Digit] -> Integer
- integralToDigits :: Integral a => a -> [Digit]
- coefficientLen :: Int
- payloadDigitsLen :: Int
- data Coefficient
- coefficient :: [Digit] -> Maybe Coefficient
- unCoefficient :: Coefficient -> [Digit]
- data Payload
- payloadDigits :: [Digit] -> Maybe Payload
- unPayload :: Payload -> [Digit]
- data Exponent
- exponent :: Int -> Maybe Exponent
- unExponent :: Exponent -> Int
- zeroExponent :: Exponent
- minMaxExp :: (Int, Int)
- data AdjustedExp
- adjustedExp :: Coefficient -> Exponent -> AdjustedExp
- unAdjustedExp :: AdjustedExp -> Int
- minNormalAdj :: AdjustedExp
- minNormalExp :: Coefficient -> Exponent
- adjustedToExponent :: Coefficient -> AdjustedExp -> Exponent
- data Sign
- data NaN
- data Value
- data Decoded = Decoded {}
- fromBCD :: Decoded -> Env Quad
- toBCD :: Quad -> Env Decoded
- fromByteString :: ByteString -> Ctx Quad
- toByteString :: Quad -> Env ByteString
- toEngByteString :: Quad -> Env ByteString
- fromInt32 :: C'int32_t -> Env Quad
- fromUInt32 :: C'uint32_t -> Env Quad
- toInt32 :: Round -> Quad -> Ctx C'int32_t
- toInt32Exact :: Round -> Quad -> Ctx C'int32_t
- toUInt32 :: Round -> Quad -> Ctx C'uint32_t
- toUInt32Exact :: Round -> Quad -> Ctx C'uint32_t
- toIntegralExact :: Quad -> Ctx Quad
- toIntegralValue :: Round -> Quad -> Ctx Quad
- add :: Quad -> Quad -> Ctx Quad
- subtract :: Quad -> Quad -> Ctx Quad
- multiply :: Quad -> Quad -> Ctx Quad
- fma :: Quad -> Quad -> Quad -> Ctx Quad
- divide :: Quad -> Quad -> Ctx Quad
- divideInteger :: Quad -> Quad -> Ctx Quad
- remainder :: Quad -> Quad -> Ctx Quad
- remainderNear :: Quad -> Quad -> Ctx Quad
- quantize :: Quad -> Quad -> Ctx Quad
- reduce :: Quad -> Ctx Quad
- compare :: Quad -> Quad -> Ctx Quad
- compareSignal :: Quad -> Quad -> Ctx Quad
- compareTotal :: Quad -> Quad -> Env Quad
- compareTotalMag :: Quad -> Quad -> Env Quad
- max :: Quad -> Quad -> Ctx Quad
- maxMag :: Quad -> Quad -> Ctx Quad
- min :: Quad -> Quad -> Ctx Quad
- minMag :: Quad -> Quad -> Ctx Quad
- sameQuantum :: Quad -> Quad -> Env Bool
- isFinite :: Quad -> Env Bool
- isInfinite :: Quad -> Env Bool
- isInteger :: Quad -> Env Bool
- isLogical :: Quad -> Env Bool
- isNaN :: Quad -> Env Bool
- isNegative :: Quad -> Env Bool
- isNormal :: Quad -> Env Bool
- isPositive :: Quad -> Env Bool
- isSignaling :: Quad -> Env Bool
- isSigned :: Quad -> Env Bool
- isSubnormal :: Quad -> Env Bool
- isZero :: Quad -> Env Bool
- plus :: Quad -> Ctx Quad
- minus :: Quad -> Ctx Quad
- abs :: Quad -> Ctx Quad
- copySign :: Quad -> Quad -> Env Quad
- nextMinus :: Quad -> Ctx Quad
- nextPlus :: Quad -> Ctx Quad
- nextToward :: Quad -> Quad -> Ctx Quad
- and :: Quad -> Quad -> Ctx Quad
- or :: Quad -> Quad -> Ctx Quad
- shift :: Quad -> Quad -> Ctx Quad
- xor :: Quad -> Quad -> Ctx Quad
- rotate :: Quad -> Quad -> Ctx Quad
- invert :: Quad -> Ctx Quad
- logB :: Quad -> Ctx Quad
- scaleB :: Quad -> Quad -> Ctx Quad
- digits :: Quad -> Env Int
- zero :: Env Quad
- version :: Env ByteString
- dIsFinite :: Decoded -> Bool
- dIsInfinite :: Decoded -> Bool
- dIsInteger :: Decoded -> Bool
- dIsLogical :: Decoded -> Bool
- dIsNaN :: Decoded -> Bool
- dIsNegative :: Decoded -> Bool
- dIsNormal :: Decoded -> Bool
- dIsPositive :: Decoded -> Bool
- dIsSignaling :: Decoded -> Bool
- dIsSigned :: Decoded -> Bool
- dIsSubnormal :: Decoded -> Bool
- dIsZero :: Decoded -> Bool
- dDigits :: Coefficient -> Int
Quad
Decimal number. This is immutable, like any Haskell value you would ordinarily work with. (Actually, that is a bit of a lie. Under the covers it is a pointer to a C struct, which is in fact mutable like anything in C. However, no function exposed in this API mutates a Quad's pointee after the Quad is created.)
As indicated in the General Decimal Arithmetic specification,
a Quad might be a finite number (perhaps the most common type)
or it might be infinite or a not-a-number. decClass will tell
you a little more about a particular Quad.
Rounding
For more on the rounding algorithms, see
Flags
For more on possible flags, see
A container for multiple Flag indicating which are set and
which are not.
Env monad
The Env monad
Since Deka is a binding to a C library, all the work happens in
the mutable land of C pointers. That means that everything
happens in the IO monad. The Env monad is simply a wrapper of
the IO monad. Since the Env data constructor is not exported,
you can't do arbitrary IO computations in the monad; you can only
do the computations from this module. Because all the
computations in this module do not create observable side
effects, it is safe to use unsafePerformIO to perform Env
computations in a pure function. This module does not have such
a function so that this module can stay Safe for Safe Haskell
purposes; however, the Data.Deka.Pure module does have such a
function.
Ctx monad
The Ctx monad
The General Decimal Arithmetic specification states that most
computations occur within a context, which affects the manner
in which computations are done (for instance, the context
determines the rounding algorithm). The context also carries
some results from computations (for instance, a computation might
set a flag to indicate that the result is rounded or inexact or
was a division by zero.) The Ctx monad carries this context.
Conceptually the Ctx monad includes the Env monad. Any Env
computation can be lifted into a Ctx computation with a
liftEnv. You will do most computations in the Ctx monad;
however, on occasion it is useful to do computations entirely in
the Env monad. You know that computations entirely in the Env
monad are unaffected by, and cannot affect, the context.
The Ctx monad captures both the context and the IO. Because
Quad is exposed only as an immutable type, and because there is
no way to do arbitrary IO in the Ctx monad (which is why it is
not an instance of the MonadIO class), it is safe to put an
unsafePerformIO on Ctx computations so they can be done in pure
functions.
The current status flags, which indicate results from previous computations.
runCtxIO :: Ctx a -> IO (a, Flags)Source
By default, rounding is half even. No status flags are set initially. Returns the final status flags along with the result of the computation.
Class
Conversions
Digits
A single decimal digit.
digitsToIntegral :: [Digit] -> IntegerSource
The most significant digit is at the head of the list.
integralToDigits :: Integral a => a -> [Digit]Source
The most significant digit is at the head of the list. Sign of number is not relevant.
Complete encoding and decoding
Coefficients
data Coefficient Source
A list of digits, less than or equal to coefficientLen long.
Corresponds only to finite numbers.
Instances
coefficient :: [Digit] -> Maybe CoefficientSource
unCoefficient :: Coefficient -> [Digit]Source
A list of digits, less than or equal to payloadDigitsLen
long.
payloadDigits :: [Digit] -> Maybe PayloadSource
Exponents
The signed integer which indicates the power of ten by which the coefficient is multiplied.
exponent :: Int -> Maybe ExponentSource
Ensures that the exponent is within the range allowed by
minMaxExp.
unExponent :: Exponent -> IntSource
data AdjustedExp Source
An adjusted exponent is the value of an exponent of a number when that number is expressed as though in scientific notation with one digit before any decimal point. This is the finite exponent + (number of significant digits - 1).
Instances
adjustedExp :: Coefficient -> Exponent -> AdjustedExpSource
minNormalAdj :: AdjustedExpSource
The smallest possible adjusted exponent that is still normal. Adjusted exponents smaller than this are subnormal.
minNormalExp :: Coefficient -> ExponentSource
Like minNormalAdj, but returns the size of the regular exponent
rather than the adjusted exponent.
Sign, NaN, Value, Decoded
fromBCD :: Decoded -> Env QuadSource
Encodes a new Quad. The result is always canonical. However,
the function does not signal if the result is an sNaN.
Strings
fromByteString :: ByteString -> Ctx QuadSource
Reads a ByteString, which can be in scientific, engineering, or "regular" decimal notation. Also reads NaN, Infinity, etc. Will return a signaling NaN and set the Invalid flag if the string given is invalid.
In the decNumber C library, this function was called
fromString; the name was changed here because it doesn't take a
regular Haskell String.
toByteString :: Quad -> Env ByteStringSource
toEngByteString :: Quad -> Env ByteStringSource
Returns a string in engineering notation.
In the decNumber C library, this is called toEngString; the
name is changed here because the function does not return a
regular Haskell String.
Integers
fromUInt32 :: C'uint32_t -> Env QuadSource
toUInt32Exact :: Round -> Quad -> Ctx C'uint32_tSource
Other Quad
toIntegralExact :: Quad -> Ctx QuadSource
Arithmetic
Exponent and coefficient adjustment
quantize :: Quad -> Quad -> Ctx QuadSource
quantize x y returns z which is x set to have the same
quantum as y; that is, numerically the same value but rounded
or padded if necessary to have the same exponent as y. Useful
for rounding monetary quantities.
Comparisons
compareSignal :: Quad -> Quad -> Ctx QuadSource
Same as compare, but a quietNaN is treated like a signaling
NaN (sets invalidOperation).
compareTotal :: Quad -> Quad -> Env QuadSource
Compares using an IEEE 754 total ordering, which takes into
account the exponent. IEEE 754 says that this function might
return different results depending upon whether the operands are
canonical; Quad are always canonical so you don't need to worry
about that here.
compareTotalMag :: Quad -> Quad -> Env QuadSource
Same as compareTotal but compares the absolute value of the
two arguments.
Tests
isInfinite :: Quad -> Env BoolSource
isInteger :: Quad -> Env BoolSource
True if x is finite and has exponent of 0; False otherwise.
This can lead to unexpected results; for instance, 3 x 10 ^ 2 is
300, but this function will return False.
isLogical :: Quad -> Env BoolSource
True only if x is zero or positive, an integer (finite with
exponent of 0), and the coefficient is only zeroes and/or ones.
isNegative :: Quad -> Env BoolSource
True only if x is less than zero and is not an NaN.
isPositive :: Quad -> Env BoolSource
True only if x is greater than zero and is not an NaN.
isSignaling :: Quad -> Env BoolSource
True only if x is a signaling NaN.
isSigned :: Quad -> Env BoolSource
True only if x has a sign of 1. Note that zeroes and NaNs
may have sign of 1.
isSubnormal :: Quad -> Env BoolSource
True only if x is subnormal - that is, finite, non-zero, and
with a magnitude less than 10 ^ emin.
Signs
plus :: Quad -> Ctx QuadSource
Same effect as 0 + x where the exponent of the zero is the
same as that of x if x is finite). NaNs are handled as for
arithmetic operations.
Absolute value. NaNs are handled normally (the sign of an NaN
is not affected, and an sNaN sets invalidOperation.
copySign :: Quad -> Quad -> Env QuadSource
copySign x y returns z, which is a copy of x but has the
sign of y. Unlike decQuadCopySign, the result is always
canonical. This function never raises any signals.
Increment and decrement
Logical, bitwise, digit shifting
and :: Quad -> Quad -> Ctx QuadSource
Digit-wise logical and. Operands must be:
- zero or positive * integers * comprise only zeroes and/or ones
If not, invalidOperation is set.
or :: Quad -> Quad -> Ctx QuadSource
Digit wise logical inclusive Or. Operands must be:
- zero or positive * integers * comprise only zeroes and/or ones
If not, invalidOperation is set.
Transcendental
Attributes
Constants
Library info
Decoded predicates
These duplicate the tests that are available in the Env monad.
dIsInfinite :: Decoded -> BoolSource
dIsInteger :: Decoded -> BoolSource
dIsLogical :: Decoded -> BoolSource
True only if x is zero or positive, an integer (finite with
exponent of 0), and the coefficient is only zeroes and/or ones.
The sign must be Sign0 (that is, you cannot have a negative
zero.)
dIsNegative :: Decoded -> BoolSource
True only if x is less than zero and is not an NaN. It's not
enough for the sign to be Sign1; the coefficient (if finite) must
be greater than zero.
dIsPositive :: Decoded -> BoolSource
dIsSignaling :: Decoded -> BoolSource
dIsSubnormal :: Decoded -> BoolSource
dDigits :: Coefficient -> IntSource
The number of significant digits. Zero returns 1.