Data.Fixed
- Package
- purescript-fixed-precision
- Repository
- lumihq/purescript-fixed-precision
This module defines a numeric type Fixed
for working with
fixed point numbers in base 10. The precision is tracked in
the types.
#Fixed Source
newtype Fixed (precision :: Precision)
A fixed point representation of a real number, with the specified precision.
A value is multiplied by the precision, truncated and stored as a big integer. That is, we approximate the number by numerator/10^precision, storing only the numerator, and carrying the precision around as type information.
The Semiring
and associated instances allow us to perform basic arithmetic
operations.
Instances
(KnownPrecision precision) => Show (Fixed precision)
Eq (Fixed precision)
Ord (Fixed precision)
(KnownPrecision precision) => Semiring (Fixed precision)
(KnownPrecision precision) => Ring (Fixed precision)
(KnownPrecision precision) => CommutativeRing (Fixed precision)
#fromInt Source
fromInt :: forall precision. KnownPrecision precision => Int -> Fixed precision
Create a Fixed
representation of an Int
.
#fromNumber Source
fromNumber :: forall precision. KnownPrecision precision => Number -> Maybe (Fixed precision)
Approximate a Number
as a Fixed
value with the specified precision.
> fromNumber 0.1234 :: Maybe (Fixed P10000)
(Just (fromNumber 0.1234 :: P10000))
> fromNumber 0.1234 :: Maybe (Fixed P100)
(Just (fromNumber 0.12 :: P100))
When given a finite Number
, this function always succeeds: the number is
truncated (rounded towards zero) to the closest possible Fixed
value.
This function only returns Nothing
if it is given NaN, or positive or
negative infinity.
> fromNumber (1.0 / 0.0) :: Maybe (Fixed P100)
Nothing
#toNumber Source
toNumber :: forall precision. KnownPrecision precision => Fixed precision -> Number
Convert a Fixed
value to a Number
.
Note: Overflow is possible here if the numerator is sufficiently large.
Consider using toString
instead.
#fromString Source
fromString :: forall precision. KnownPrecision precision => String -> Maybe (Fixed precision)
Parse a fixed-precision number from a string. Any decimal digits which are not representable in the specified precision will be ignored.
> fromString "123.456" :: Maybe (Fixed P1000)
(Just (fromString "123.456" :: P1000))
Where possible, this function should be preferred over fromNumber
, since
it is exact (whereas fromNumber
can only provide an approximation for
larger inputs).
> fromString "9007199254740992.5" :: Maybe (Fixed P10)
(Just (fromString "9007199254740992.5" :: P10))
> fromNumber 9007199254740992.5 :: Maybe (Fixed P10)
(Just (fromString "9007199254740992.0" :: P10))
#toString Source
toString :: forall precision. KnownPrecision precision => Fixed precision -> String
Represent a Fixed
value as a string, using all of the decimal places it
can represent (based on its precision).
> map toString (fromString "100.5" :: Maybe (Fixed P10))
(Just "100.5")
> map toString (fromString "100.5" :: Maybe (Fixed P100))
(Just "100.50")
#toStringWithPrecision Source
toStringWithPrecision :: forall precision. KnownPrecision precision => Int -> Fixed precision -> String
Represent a Fixed
value as a string, with the given number of decimal
places.
> map (toStringWithPrecision 2) (fromString "1234.567" :: Maybe (Fixed P1000))
(Just "1234.56")
If more decimal places are asked for than the type can provide, the extra decimal places will be provided as zeroes.
> map (toStringWithPrecision 3) (fromString "1234.5" :: Maybe (Fixed P10))
(Just "1234.500")
#floor Source
floor :: forall precision. KnownPrecision precision => Fixed precision -> Fixed precision
Calculate the largest whole number smaller than or equal to the provided value.
> map floor $ fromNumber 0.1 :: Maybe (Fixed P10)
(Just (fromNumber 0.0 :: P10))
> map floor $ fromNumber 1.0 :: Maybe (Fixed P10)
(Just (fromNumber 1.0 :: P10))
> floor $ fromNumber (-0.1) :: Maybe (Fixed P10)
(Just (fromNumber (-1.0) :: P10))
#ceil Source
ceil :: forall precision. KnownPrecision precision => Fixed precision -> Fixed precision
Calculate the smallest whole number greater than or equal to the provided value.
> map ceil $ fromNumber 0.1 :: Maybe (Fixed P10)
(Just (fromNumber 1.0 :: P10))
> map ceil $ fromNumber 1.0 :: Maybe (Fixed P10)
(Just (fromNumber 1.0 :: P10))
> map ceil $ fromNumber (-0.1) :: Maybe (Fixed P10)
(Just (fromNumber 0.0 :: P10))
#round Source
round :: forall precision. KnownPrecision precision => Fixed precision -> Fixed precision
Round the specified value to the nearest whole number.
> map round $ fromNumber 0.1 :: Maybe (Fixed P10)
(Just (fromNumber 0.0 :: P10))
> map round $ fromNumber 0.9 :: Maybe (Fixed P10)
(Just (fromNumber 1.0 :: P10))
> map round $ fromNumber 0.5 :: Maybe (Fixed P10)
(Just (fromNumber 1.0 :: P10))
> map round $ fromNumber (-0.1) :: Maybe (Fixed P10)
(Just (fromNumber 0.0 :: P10))
#approxDiv Source
approxDiv :: forall precision. KnownPrecision precision => Fixed precision -> Fixed precision -> Fixed precision
Approximate division of fixed-precision numbers.
> lift2 approxDiv (fromNumber 22.0) (fromNumber 7.0) :: Maybe (Fixed P100)
(Just (fromNumber 3.14 :: P100))
Note: Fixed
is not a EuclideanRing
in general - it is not even
an integral domain, since it has non-zero zero-divisors:
> lift2 (*) (fromNumber 0.1) (fromNumber 0.1) :: Maybe (Fixed P10)
(Just (fromNumber 0.0 :: P10))
#TenTimes Source
data TenTimes :: Precision -> Precision
One more decimal place
Instances
(KnownPrecision p) => KnownPrecision (TenTimes p)
#KnownPrecision Source
class KnownPrecision (precision :: Precision) where
Precision which is known, i.e. it can be reflected to a
value at runtime, given a PProxy
.
reflectPrecision
returns a multiple of ten, corresponding
to the maximum number of decimal places which can be stored.
> reflectPrecision (PProxy :: PProxy P1000)
1000
Members
reflectPrecision :: PProxy precision -> BigInt
Instances
KnownPrecision One
(KnownPrecision p) => KnownPrecision (TenTimes p)
#reflectPrecisionDecimalPlaces Source
reflectPrecisionDecimalPlaces :: forall precision. KnownPrecision precision => PProxy precision -> Int
Get the number of decimal places associated with a given Precision
at
the value level.
> reflectPrecisionDecimalPlaces (PProxy :: PProxy P1000)
3
#reifyPrecision Source
reifyPrecision :: forall r. Int -> (forall precision. KnownPrecision precision => PProxy precision -> r) -> Maybe r
Reify an non-negative integer (a power of ten) as a Precision
.
For example
> reifyPrecision 0 reflectPrecision
Just 1
> reifyPrecision 1 reflectPrecision
Just 10
> reifyPrecision 2 reflectPrecision
Just 100
> reifyPrecision (-1) reflectPrecision
Nothing
- Modules
- Data.
Fixed