Portability | non-portable (GHC extensions) |
---|---|
Stability | experimental |
Maintainer | Daniel Fischer <daniel.is.fischer@googlemail.com> |
Lower level conversion of base-2 numbers to base-10 representations.
These functions can be used to define Show
instances for types which
don't support the full RealFloat
interface but have an analogue to
decodeFloat
(and maybe to isNaN
, isInfinite
and isNegativeZero
).
- class BinDecode a where
- class (Num a, Ord a, BinDecode a) => DecimalFormat a where
- data FormatStyle
- decimalFormat :: DecimalFormat a => FormatStyle -> Maybe Int -> a -> String
- binDecFormat :: BinDecode a => FormatStyle -> Maybe Int -> a -> String
- rawFormat :: (a -> (Int, Integer, Int)) -> Int -> FormatStyle -> Maybe Int -> a -> String
- fullRawFormat :: (a -> (Int, Integer, Int)) -> FormatStyle -> a -> String
- formatDigits :: FormatStyle -> Int -> Maybe Int -> [Int] -> Int -> String
- posToDigits :: Int -> Int -> Integer -> Int -> ([Int], Int)
- fullDecimalDigits :: Int -> Int -> Int
- integerLog2 :: Integer -> Int
Classes
Class for types whose values can be decoded into the form
m * 2^e
with an Integer
mantissa m
and an Int
exponent e
.
Minimal complete definition: one of decode
and decodeL
.
It is strongly recommended to override the default implementation
of showDigits
if the datatype allows distinguishing values
without using an exact representation.
decode :: a -> (Integer, Int)Source
decode
is analogous to decodeFloat
.
decodeL :: a -> (Int, Integer, Int)Source
decodeL
gives the integer base-2
logarithm of the mantissa
in addition to the result of decode
. If the absolute value of
the mantissa always has the same highest set bit (excepting 0
),
specifying that as a constant will be faster than calculating the
logarithm for each individual mantissa.
If x = m*2^e
with m /= 0
, then
must hold.
decodeL
x == (integerLog2
(abs m), m, e)
showDigits :: a -> IntSource
The number of significant digits needed to uniquely determine the
value (or however many digits are desired). Usually, showDigits
will be a constant function, but that is not necessary. However,
all values of showDigits
must be positive.
If the mantissa always has the same highest bit, highBit
, set
when it is nonzero,
showDigits
_ = 2 +floor
((highBit+1) * 'logBase 10 2)
is sufficient to make the values and formatted String
s
uniquely determine each other and in general this is the smallest
number to achieve that (calculate the number once and supply the
result as a constant).
If the highest set bit of nonzero mantissae varies, things are not
so easy. If the width of mantissae is bounded, plugging the largest
possible value into the above formula works, but may yield an unduly
large number for common cases. Using the formula with highBit
determined by the mantissa almost works, but if the representation
is rounded at all, with sufficiently many bits in the mantissa,
there will be values between the original and the representation.
So, with mantissae of width varying over a large range, the only
feasible way of obtaining a bijection between values and their
decimal representations is printing to full precision in
general, optionally capping atthe upper limit.
The default implementation prints values exactly, which in general
is undesirable because it involves huge Integer
s and long
representations.
class (Num a, Ord a, BinDecode a) => DecimalFormat a whereSource
Class for types whose values may be NaN
or infinite and can
otherwise be decoded into the form m * 2^e
.
Format type
data FormatStyle Source
The Style in which to format the display String
Exponent | Display in scientific notation, e.g. |
Fixed | Display in standard decimal notation, e.g. |
Generic (Maybe (Int, Int)) | Use |
Functions
Medium level
decimalFormat :: DecimalFormat a => FormatStyle -> Maybe Int -> a -> StringSource
decimalFormat
is a slightly higher-level formatter, treating the
special cases of NaN
and infinities.
binDecFormat :: BinDecode a => FormatStyle -> Maybe Int -> a -> StringSource
binDecFormat
is the formatter for instances of the BinDecode
class. Any special values must be processed before it is called.
It fills in the missing arguments before calling rawFormat
.
Low level
:: (a -> (Int, Integer, Int)) | decoder, same restrictions as |
-> Int | number of significant digits |
-> FormatStyle | formatting style |
-> Maybe Int | desired precision |
-> a | value to be displayed |
-> String |
rawFormat
is a low-level formatter. The sign is determined from
the sign of the mantissa.
:: (a -> (Int, Integer, Int)) | decoder, same restriction as |
-> FormatStyle | formatting style |
-> a | value to be displayed |
-> String |
fullRawFormat
is a low-level formatter producing an exact representation
of a value which can be decoded into the form m * 2^e
.
:: FormatStyle | formatting style |
-> Int | number of significant digits required |
-> Maybe Int | desired precision |
-> [Int] | list of significant digits |
-> Int | base- |
-> String |
formatDigits
builds the display String
from the digits and
the exponent of a nonnegative number.
Dangerous
:: Int | number of digits required |
-> Int | base |
-> Integer | mantissa |
-> Int | scaling exponent |
-> ([Int], Int) |
posToDigits
converts a positive number into a list of digits and
an exponent. If x = 10^e*d_1.d_2...d_m...
with d_1 /= 0
and
0 <= d_i <= 9
, the result is ([d_1,d_2,...,d_m],e)
, where
m
is one or two larger than the number of requested digits,
provided that 2^(-70776) <= x < 2^248236
(with 64-bit Int
s,
the upper bound is about 2^1.3e9
).
The number x
is (indirectly) given in the form
mantissa * 2^exponent
, similar to encodeFloat
,
as the final two arguments. The second argument is the base-2
logarithm of the mantissa and the first is the number of decimal
digits needed to discriminate between different numbers.
In
, it is assumed that
posToDigits
digs mlog mant exp
-
digs > 0
,mlog >= 0
, -
2^mlog <= mant < 2^(mlog+1)
.
These assumptions are not checked, and if they're not satisfied, wrong results or worse are the consequences. You have been warned.
The digits argument may be smaller than would be necessary to uniquely determine each value if that is not required. As a rule of thumb, requiring fewer significant digits means faster generation of the representation.
Auxiliary
fullDecimalDigits :: Int -> Int -> IntSource
calculates the number of decimal digits that
may be required to exactly display a value fullDecimalDigits
a ex = m * 2^e
where m
is
an Integer
satisfying 2^a <= m < 2^(a+1)
. Usually, the calculated
value is not much larger than the actual number of digits in the
exact decimal representation, but it will be if the exponent e
is negative and has large absolute value and the mantissa is divisible
by a large power of 2
.
integerLog2 :: Integer -> IntSource
Integer base-2
logarithm of a positive Integer
.