{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
module Numeric.Decimal
(
module Numeric.Decimal.BoundedArithmetic
, module Numeric.Decimal.Internal
, RoundHalfUp
, roundHalfUp
, RoundHalfDown
, roundHalfDown
, RoundHalfEven
, roundHalfEven
, RoundHalfToZero
, roundHalfToZero
, RoundHalfFromZero
, roundHalfFromZero
, RoundDown
, Floor
, roundDown
, RoundToZero
, Truncate
, roundToZero
, decimalList
, sumDecimalBounded
, productDecimalBoundedWithRounding
, FixedScale
, toFixedDecimal
, fromFixedDecimal
, fromFixedDecimalBounded
, toScientificDecimal
, fromScientificDecimal
, fromScientificDecimalBounded
) where
import Control.Exception
import Control.Monad
import Control.Monad.Catch
import Data.Coerce
import Data.Fixed
import Data.Int
import Data.Proxy
import Data.Scientific
import Data.Word
import GHC.TypeLits
import Numeric.Decimal.BoundedArithmetic
import Numeric.Decimal.Internal
data RoundHalfUp
instance Round RoundHalfUp Integer where
roundDecimal :: Decimal RoundHalfUp (n + k) Integer
-> Decimal RoundHalfUp n Integer
roundDecimal = Decimal RoundHalfUp (n + k) Integer
-> Decimal RoundHalfUp n Integer
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfUp
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfUp Int where
roundDecimal :: Decimal RoundHalfUp (n + k) Int -> Decimal RoundHalfUp n Int
roundDecimal = Decimal RoundHalfUp (n + k) Int -> Decimal RoundHalfUp n Int
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfUp
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfUp Int8 where
roundDecimal :: Decimal RoundHalfUp (n + k) Int8 -> Decimal RoundHalfUp n Int8
roundDecimal = Decimal RoundHalfUp (n + k) Int8 -> Decimal RoundHalfUp n Int8
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfUp
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfUp Int16 where
roundDecimal :: Decimal RoundHalfUp (n + k) Int16 -> Decimal RoundHalfUp n Int16
roundDecimal = Decimal RoundHalfUp (n + k) Int16 -> Decimal RoundHalfUp n Int16
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfUp
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfUp Int32 where
roundDecimal :: Decimal RoundHalfUp (n + k) Int32 -> Decimal RoundHalfUp n Int32
roundDecimal = Decimal RoundHalfUp (n + k) Int32 -> Decimal RoundHalfUp n Int32
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfUp
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfUp Int64 where
roundDecimal :: Decimal RoundHalfUp (n + k) Int64 -> Decimal RoundHalfUp n Int64
roundDecimal = Decimal RoundHalfUp (n + k) Int64 -> Decimal RoundHalfUp n Int64
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfUp
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfUp Word where
roundDecimal :: Decimal RoundHalfUp (n + k) Word -> Decimal RoundHalfUp n Word
roundDecimal = Decimal RoundHalfUp (n + k) Word -> Decimal RoundHalfUp n Word
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfUp
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfUp Word8 where
roundDecimal :: Decimal RoundHalfUp (n + k) Word8 -> Decimal RoundHalfUp n Word8
roundDecimal = Decimal RoundHalfUp (n + k) Word8 -> Decimal RoundHalfUp n Word8
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfUp
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfUp Word16 where
roundDecimal :: Decimal RoundHalfUp (n + k) Word16 -> Decimal RoundHalfUp n Word16
roundDecimal = Decimal RoundHalfUp (n + k) Word16 -> Decimal RoundHalfUp n Word16
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfUp
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfUp Word32 where
roundDecimal :: Decimal RoundHalfUp (n + k) Word32 -> Decimal RoundHalfUp n Word32
roundDecimal = Decimal RoundHalfUp (n + k) Word32 -> Decimal RoundHalfUp n Word32
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfUp
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfUp Word64 where
roundDecimal :: Decimal RoundHalfUp (n + k) Word64 -> Decimal RoundHalfUp n Word64
roundDecimal = Decimal RoundHalfUp (n + k) Word64 -> Decimal RoundHalfUp n Word64
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfUp
{-# INLINABLE roundDecimal #-}
roundHalfUp :: forall r n k p . (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p
roundHalfUp :: Decimal r (n + k) p -> Decimal r n p
roundHalfUp (Decimal p
x)
| Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal p
x
| p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
>= p
s1 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (p
q p -> p -> p
forall a. Num a => a -> a -> a
+ p
1)
| p -> p
forall a. Num a => a -> a
signum p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
< p
0 Bool -> Bool -> Bool
&& p -> p
forall a. Num a => a -> a
abs p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
> p
s1 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (p
q p -> p -> p
forall a. Num a => a -> a -> a
- p
1)
| Bool
otherwise = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal p
q
where
k :: Int
k = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy k -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy k
forall k (t :: k). Proxy t
Proxy :: Proxy k)) :: Int
s1 :: p
s1 = p
10 p -> Int -> p
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
k
(p
q, p
r) = (p
2 p -> p -> p
forall a. Num a => a -> a -> a
*) (p -> p) -> (p, p) -> (p, p)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p -> p -> (p, p)
forall a. Integral a => a -> a -> (a, a)
quotRem p
x p
s1
{-# INLINABLE roundHalfUp #-}
data RoundHalfDown
instance Round RoundHalfDown Integer where
roundDecimal :: Decimal RoundHalfDown (n + k) Integer
-> Decimal RoundHalfDown n Integer
roundDecimal = Decimal RoundHalfDown (n + k) Integer
-> Decimal RoundHalfDown n Integer
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfDown
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfDown Int where
roundDecimal :: Decimal RoundHalfDown (n + k) Int -> Decimal RoundHalfDown n Int
roundDecimal = Decimal RoundHalfDown (n + k) Int -> Decimal RoundHalfDown n Int
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfDown
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfDown Int8 where
roundDecimal :: Decimal RoundHalfDown (n + k) Int8 -> Decimal RoundHalfDown n Int8
roundDecimal = Decimal RoundHalfDown (n + k) Int8 -> Decimal RoundHalfDown n Int8
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfDown
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfDown Int16 where
roundDecimal :: Decimal RoundHalfDown (n + k) Int16
-> Decimal RoundHalfDown n Int16
roundDecimal = Decimal RoundHalfDown (n + k) Int16
-> Decimal RoundHalfDown n Int16
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfDown
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfDown Int32 where
roundDecimal :: Decimal RoundHalfDown (n + k) Int32
-> Decimal RoundHalfDown n Int32
roundDecimal = Decimal RoundHalfDown (n + k) Int32
-> Decimal RoundHalfDown n Int32
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfDown
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfDown Int64 where
roundDecimal :: Decimal RoundHalfDown (n + k) Int64
-> Decimal RoundHalfDown n Int64
roundDecimal = Decimal RoundHalfDown (n + k) Int64
-> Decimal RoundHalfDown n Int64
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfDown
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfDown Word where
roundDecimal :: Decimal RoundHalfDown (n + k) Word -> Decimal RoundHalfDown n Word
roundDecimal = Decimal RoundHalfDown (n + k) Word -> Decimal RoundHalfDown n Word
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfDown
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfDown Word8 where
roundDecimal :: Decimal RoundHalfDown (n + k) Word8
-> Decimal RoundHalfDown n Word8
roundDecimal = Decimal RoundHalfDown (n + k) Word8
-> Decimal RoundHalfDown n Word8
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfDown
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfDown Word16 where
roundDecimal :: Decimal RoundHalfDown (n + k) Word16
-> Decimal RoundHalfDown n Word16
roundDecimal = Decimal RoundHalfDown (n + k) Word16
-> Decimal RoundHalfDown n Word16
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfDown
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfDown Word32 where
roundDecimal :: Decimal RoundHalfDown (n + k) Word32
-> Decimal RoundHalfDown n Word32
roundDecimal = Decimal RoundHalfDown (n + k) Word32
-> Decimal RoundHalfDown n Word32
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfDown
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfDown Word64 where
roundDecimal :: Decimal RoundHalfDown (n + k) Word64
-> Decimal RoundHalfDown n Word64
roundDecimal = Decimal RoundHalfDown (n + k) Word64
-> Decimal RoundHalfDown n Word64
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfDown
{-# INLINABLE roundDecimal #-}
roundHalfDown :: forall r n k p . (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p
roundHalfDown :: Decimal r (n + k) p -> Decimal r n p
roundHalfDown (Decimal p
x)
| Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal p
x
| p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
> p
s1 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (p
q p -> p -> p
forall a. Num a => a -> a -> a
+ p
1)
| p -> p
forall a. Num a => a -> a
signum p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
< p
0 Bool -> Bool -> Bool
&& p -> p
forall a. Num a => a -> a
abs p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
>= p
s1 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (p
q p -> p -> p
forall a. Num a => a -> a -> a
- p
1)
| Bool
otherwise = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal p
q
where
k :: Int
k = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy k -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy k
forall k (t :: k). Proxy t
Proxy :: Proxy k)) :: Int
s1 :: p
s1 = p
10 p -> Int -> p
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
k
(p
q, p
r) = (p
2 p -> p -> p
forall a. Num a => a -> a -> a
*) (p -> p) -> (p, p) -> (p, p)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p -> p -> (p, p)
forall a. Integral a => a -> a -> (a, a)
quotRem p
x p
s1
{-# INLINABLE roundHalfDown #-}
data RoundHalfEven
instance Round RoundHalfEven Integer where
roundDecimal :: Decimal RoundHalfEven (n + k) Integer
-> Decimal RoundHalfEven n Integer
roundDecimal = Decimal RoundHalfEven (n + k) Integer
-> Decimal RoundHalfEven n Integer
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfEven
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfEven Int where
roundDecimal :: Decimal RoundHalfEven (n + k) Int -> Decimal RoundHalfEven n Int
roundDecimal = Decimal RoundHalfEven (n + k) Int -> Decimal RoundHalfEven n Int
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfEven
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfEven Int8 where
roundDecimal :: Decimal RoundHalfEven (n + k) Int8 -> Decimal RoundHalfEven n Int8
roundDecimal = Decimal RoundHalfEven (n + k) Int8 -> Decimal RoundHalfEven n Int8
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfEven
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfEven Int16 where
roundDecimal :: Decimal RoundHalfEven (n + k) Int16
-> Decimal RoundHalfEven n Int16
roundDecimal = Decimal RoundHalfEven (n + k) Int16
-> Decimal RoundHalfEven n Int16
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfEven
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfEven Int32 where
roundDecimal :: Decimal RoundHalfEven (n + k) Int32
-> Decimal RoundHalfEven n Int32
roundDecimal = Decimal RoundHalfEven (n + k) Int32
-> Decimal RoundHalfEven n Int32
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfEven
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfEven Int64 where
roundDecimal :: Decimal RoundHalfEven (n + k) Int64
-> Decimal RoundHalfEven n Int64
roundDecimal = Decimal RoundHalfEven (n + k) Int64
-> Decimal RoundHalfEven n Int64
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfEven
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfEven Word where
roundDecimal :: Decimal RoundHalfEven (n + k) Word -> Decimal RoundHalfEven n Word
roundDecimal = Decimal RoundHalfEven (n + k) Word -> Decimal RoundHalfEven n Word
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfEven
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfEven Word8 where
roundDecimal :: Decimal RoundHalfEven (n + k) Word8
-> Decimal RoundHalfEven n Word8
roundDecimal = Decimal RoundHalfEven (n + k) Word8
-> Decimal RoundHalfEven n Word8
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfEven
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfEven Word16 where
roundDecimal :: Decimal RoundHalfEven (n + k) Word16
-> Decimal RoundHalfEven n Word16
roundDecimal = Decimal RoundHalfEven (n + k) Word16
-> Decimal RoundHalfEven n Word16
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfEven
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfEven Word32 where
roundDecimal :: Decimal RoundHalfEven (n + k) Word32
-> Decimal RoundHalfEven n Word32
roundDecimal = Decimal RoundHalfEven (n + k) Word32
-> Decimal RoundHalfEven n Word32
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfEven
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfEven Word64 where
roundDecimal :: Decimal RoundHalfEven (n + k) Word64
-> Decimal RoundHalfEven n Word64
roundDecimal = Decimal RoundHalfEven (n + k) Word64
-> Decimal RoundHalfEven n Word64
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfEven
{-# INLINABLE roundDecimal #-}
roundHalfEven :: forall r n k p . (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p
roundHalfEven :: Decimal r (n + k) p -> Decimal r n p
roundHalfEven (Decimal p
x)
| Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal p
x
| p -> p
forall a. Num a => a -> a
abs p
r p -> p -> Bool
forall a. Eq a => a -> a -> Bool
== p
s1 Bool -> Bool -> Bool
&& p -> Bool
forall a. Integral a => a -> Bool
odd p
q = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (p
q p -> p -> p
forall a. Num a => a -> a -> a
+ p -> p
forall a. Num a => a -> a
signum p
r)
| p -> p
forall a. Num a => a -> a
abs p
r p -> p -> Bool
forall a. Eq a => a -> a -> Bool
== p
s1 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal p
q
| p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
> p
s1 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (p
q p -> p -> p
forall a. Num a => a -> a -> a
+ p
1)
| p -> p
forall a. Num a => a -> a
signum p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
< p
0 Bool -> Bool -> Bool
&& p -> p
forall a. Num a => a -> a
abs p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
> p
s1 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (p
q p -> p -> p
forall a. Num a => a -> a -> a
- p
1)
| Bool
otherwise = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal p
q
where
k :: Int
k = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy k -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy k
forall k (t :: k). Proxy t
Proxy :: Proxy k)) :: Int
s1 :: p
s1 = p
10 p -> Int -> p
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
k
(p
q, p
r) = (p
2 p -> p -> p
forall a. Num a => a -> a -> a
*) (p -> p) -> (p, p) -> (p, p)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p -> p -> (p, p)
forall a. Integral a => a -> a -> (a, a)
quotRem p
x p
s1
{-# INLINABLE roundHalfEven #-}
data RoundHalfToZero
instance Round RoundHalfToZero Integer where
roundDecimal :: Decimal RoundHalfToZero (n + k) Integer
-> Decimal RoundHalfToZero n Integer
roundDecimal = Decimal RoundHalfToZero (n + k) Integer
-> Decimal RoundHalfToZero n Integer
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfToZero Int where
roundDecimal :: Decimal RoundHalfToZero (n + k) Int
-> Decimal RoundHalfToZero n Int
roundDecimal = Decimal RoundHalfToZero (n + k) Int
-> Decimal RoundHalfToZero n Int
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfToZero Int8 where
roundDecimal :: Decimal RoundHalfToZero (n + k) Int8
-> Decimal RoundHalfToZero n Int8
roundDecimal = Decimal RoundHalfToZero (n + k) Int8
-> Decimal RoundHalfToZero n Int8
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfToZero Int16 where
roundDecimal :: Decimal RoundHalfToZero (n + k) Int16
-> Decimal RoundHalfToZero n Int16
roundDecimal = Decimal RoundHalfToZero (n + k) Int16
-> Decimal RoundHalfToZero n Int16
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfToZero Int32 where
roundDecimal :: Decimal RoundHalfToZero (n + k) Int32
-> Decimal RoundHalfToZero n Int32
roundDecimal = Decimal RoundHalfToZero (n + k) Int32
-> Decimal RoundHalfToZero n Int32
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfToZero Int64 where
roundDecimal :: Decimal RoundHalfToZero (n + k) Int64
-> Decimal RoundHalfToZero n Int64
roundDecimal = Decimal RoundHalfToZero (n + k) Int64
-> Decimal RoundHalfToZero n Int64
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfToZero Word where
roundDecimal :: Decimal RoundHalfToZero (n + k) Word
-> Decimal RoundHalfToZero n Word
roundDecimal = Decimal RoundHalfToZero (n + k) Word
-> Decimal RoundHalfToZero n Word
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfToZero Word8 where
roundDecimal :: Decimal RoundHalfToZero (n + k) Word8
-> Decimal RoundHalfToZero n Word8
roundDecimal = Decimal RoundHalfToZero (n + k) Word8
-> Decimal RoundHalfToZero n Word8
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfToZero Word16 where
roundDecimal :: Decimal RoundHalfToZero (n + k) Word16
-> Decimal RoundHalfToZero n Word16
roundDecimal = Decimal RoundHalfToZero (n + k) Word16
-> Decimal RoundHalfToZero n Word16
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfToZero Word32 where
roundDecimal :: Decimal RoundHalfToZero (n + k) Word32
-> Decimal RoundHalfToZero n Word32
roundDecimal = Decimal RoundHalfToZero (n + k) Word32
-> Decimal RoundHalfToZero n Word32
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfToZero Word64 where
roundDecimal :: Decimal RoundHalfToZero (n + k) Word64
-> Decimal RoundHalfToZero n Word64
roundDecimal = Decimal RoundHalfToZero (n + k) Word64
-> Decimal RoundHalfToZero n Word64
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfToZero
{-# INLINABLE roundDecimal #-}
roundHalfToZero :: forall r n k p . (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p
roundHalfToZero :: Decimal r (n + k) p -> Decimal r n p
roundHalfToZero (Decimal p
x)
| Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal p
x
| p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
> p
s1 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (p
q p -> p -> p
forall a. Num a => a -> a -> a
+ p
1)
| p -> p
forall a. Num a => a -> a
signum p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
< p
0 Bool -> Bool -> Bool
&& p -> p
forall a. Num a => a -> a
abs p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
> p
s1 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (p
q p -> p -> p
forall a. Num a => a -> a -> a
- p
1)
| Bool
otherwise = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal p
q
where
k :: Int
k = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy k -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy k
forall k (t :: k). Proxy t
Proxy :: Proxy k)) :: Int
s1 :: p
s1 = p
10 p -> Int -> p
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
k
(p
q, p
r) = (p
2 p -> p -> p
forall a. Num a => a -> a -> a
*) (p -> p) -> (p, p) -> (p, p)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p -> p -> (p, p)
forall a. Integral a => a -> a -> (a, a)
quotRem p
x p
s1
{-# INLINABLE roundHalfToZero #-}
data RoundHalfFromZero
instance Round RoundHalfFromZero Integer where
roundDecimal :: Decimal RoundHalfFromZero (n + k) Integer
-> Decimal RoundHalfFromZero n Integer
roundDecimal = Decimal RoundHalfFromZero (n + k) Integer
-> Decimal RoundHalfFromZero n Integer
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfFromZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfFromZero Int where
roundDecimal :: Decimal RoundHalfFromZero (n + k) Int
-> Decimal RoundHalfFromZero n Int
roundDecimal = Decimal RoundHalfFromZero (n + k) Int
-> Decimal RoundHalfFromZero n Int
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfFromZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfFromZero Int8 where
roundDecimal :: Decimal RoundHalfFromZero (n + k) Int8
-> Decimal RoundHalfFromZero n Int8
roundDecimal = Decimal RoundHalfFromZero (n + k) Int8
-> Decimal RoundHalfFromZero n Int8
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfFromZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfFromZero Int16 where
roundDecimal :: Decimal RoundHalfFromZero (n + k) Int16
-> Decimal RoundHalfFromZero n Int16
roundDecimal = Decimal RoundHalfFromZero (n + k) Int16
-> Decimal RoundHalfFromZero n Int16
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfFromZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfFromZero Int32 where
roundDecimal :: Decimal RoundHalfFromZero (n + k) Int32
-> Decimal RoundHalfFromZero n Int32
roundDecimal = Decimal RoundHalfFromZero (n + k) Int32
-> Decimal RoundHalfFromZero n Int32
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfFromZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfFromZero Int64 where
roundDecimal :: Decimal RoundHalfFromZero (n + k) Int64
-> Decimal RoundHalfFromZero n Int64
roundDecimal = Decimal RoundHalfFromZero (n + k) Int64
-> Decimal RoundHalfFromZero n Int64
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfFromZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfFromZero Word where
roundDecimal :: Decimal RoundHalfFromZero (n + k) Word
-> Decimal RoundHalfFromZero n Word
roundDecimal = Decimal RoundHalfFromZero (n + k) Word
-> Decimal RoundHalfFromZero n Word
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfFromZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfFromZero Word8 where
roundDecimal :: Decimal RoundHalfFromZero (n + k) Word8
-> Decimal RoundHalfFromZero n Word8
roundDecimal = Decimal RoundHalfFromZero (n + k) Word8
-> Decimal RoundHalfFromZero n Word8
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfFromZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfFromZero Word16 where
roundDecimal :: Decimal RoundHalfFromZero (n + k) Word16
-> Decimal RoundHalfFromZero n Word16
roundDecimal = Decimal RoundHalfFromZero (n + k) Word16
-> Decimal RoundHalfFromZero n Word16
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfFromZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfFromZero Word32 where
roundDecimal :: Decimal RoundHalfFromZero (n + k) Word32
-> Decimal RoundHalfFromZero n Word32
roundDecimal = Decimal RoundHalfFromZero (n + k) Word32
-> Decimal RoundHalfFromZero n Word32
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfFromZero
{-# INLINABLE roundDecimal #-}
instance Round RoundHalfFromZero Word64 where
roundDecimal :: Decimal RoundHalfFromZero (n + k) Word64
-> Decimal RoundHalfFromZero n Word64
roundDecimal = Decimal RoundHalfFromZero (n + k) Word64
-> Decimal RoundHalfFromZero n Word64
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundHalfFromZero
{-# INLINABLE roundDecimal #-}
roundHalfFromZero :: forall r n k p . (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p
roundHalfFromZero :: Decimal r (n + k) p -> Decimal r n p
roundHalfFromZero (Decimal p
x)
| Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal p
x
| p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
>= p
s1 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (p
q p -> p -> p
forall a. Num a => a -> a -> a
+ p
1)
| p -> p
forall a. Num a => a -> a
signum p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
< p
0 Bool -> Bool -> Bool
&& p -> p
forall a. Num a => a -> a
abs p
r p -> p -> Bool
forall a. Ord a => a -> a -> Bool
>= p
s1 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (p
q p -> p -> p
forall a. Num a => a -> a -> a
- p
1)
| Bool
otherwise = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal p
q
where
k :: Int
k = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy k -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy k
forall k (t :: k). Proxy t
Proxy :: Proxy k)) :: Int
s1 :: p
s1 = p
10 p -> Int -> p
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
k
(p
q, p
r) = (p
2 p -> p -> p
forall a. Num a => a -> a -> a
*) (p -> p) -> (p, p) -> (p, p)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p -> p -> (p, p)
forall a. Integral a => a -> a -> (a, a)
quotRem p
x p
s1
{-# INLINABLE roundHalfFromZero #-}
data RoundDown
type Floor = RoundDown
instance Round RoundDown Integer where
roundDecimal :: Decimal RoundDown (n + k) Integer -> Decimal RoundDown n Integer
roundDecimal = Decimal RoundDown (n + k) Integer -> Decimal RoundDown n Integer
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundDown
instance Round RoundDown Int where
roundDecimal :: Decimal RoundDown (n + k) Int -> Decimal RoundDown n Int
roundDecimal = Decimal RoundDown (n + k) Int -> Decimal RoundDown n Int
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundDown
{-# INLINABLE roundDecimal #-}
instance Round RoundDown Int8 where
roundDecimal :: Decimal RoundDown (n + k) Int8 -> Decimal RoundDown n Int8
roundDecimal = Decimal RoundDown (n + k) Int8 -> Decimal RoundDown n Int8
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundDown
{-# INLINABLE roundDecimal #-}
instance Round RoundDown Int16 where
roundDecimal :: Decimal RoundDown (n + k) Int16 -> Decimal RoundDown n Int16
roundDecimal = Decimal RoundDown (n + k) Int16 -> Decimal RoundDown n Int16
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundDown
{-# INLINABLE roundDecimal #-}
instance Round RoundDown Int32 where
roundDecimal :: Decimal RoundDown (n + k) Int32 -> Decimal RoundDown n Int32
roundDecimal = Decimal RoundDown (n + k) Int32 -> Decimal RoundDown n Int32
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundDown
{-# INLINABLE roundDecimal #-}
instance Round RoundDown Int64 where
roundDecimal :: Decimal RoundDown (n + k) Int64 -> Decimal RoundDown n Int64
roundDecimal = Decimal RoundDown (n + k) Int64 -> Decimal RoundDown n Int64
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundDown
{-# INLINABLE roundDecimal #-}
instance Round RoundDown Word where
roundDecimal :: Decimal RoundDown (n + k) Word -> Decimal RoundDown n Word
roundDecimal = Decimal RoundDown (n + k) Word -> Decimal RoundDown n Word
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundDown
{-# INLINABLE roundDecimal #-}
instance Round RoundDown Word8 where
roundDecimal :: Decimal RoundDown (n + k) Word8 -> Decimal RoundDown n Word8
roundDecimal = Decimal RoundDown (n + k) Word8 -> Decimal RoundDown n Word8
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundDown
{-# INLINABLE roundDecimal #-}
instance Round RoundDown Word16 where
roundDecimal :: Decimal RoundDown (n + k) Word16 -> Decimal RoundDown n Word16
roundDecimal = Decimal RoundDown (n + k) Word16 -> Decimal RoundDown n Word16
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundDown
{-# INLINABLE roundDecimal #-}
instance Round RoundDown Word32 where
roundDecimal :: Decimal RoundDown (n + k) Word32 -> Decimal RoundDown n Word32
roundDecimal = Decimal RoundDown (n + k) Word32 -> Decimal RoundDown n Word32
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundDown
{-# INLINABLE roundDecimal #-}
instance Round RoundDown Word64 where
roundDecimal :: Decimal RoundDown (n + k) Word64 -> Decimal RoundDown n Word64
roundDecimal = Decimal RoundDown (n + k) Word64 -> Decimal RoundDown n Word64
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundDown
{-# INLINABLE roundDecimal #-}
roundDown :: forall r n k p . (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p
roundDown :: Decimal r (n + k) p -> Decimal r n p
roundDown (Decimal p
x)
| p
x p -> p -> Bool
forall a. Ord a => a -> a -> Bool
>= p
0 Bool -> Bool -> Bool
|| p
r p -> p -> Bool
forall a. Eq a => a -> a -> Bool
== p
0 = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal p
q
| Bool
otherwise = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (p
q p -> p -> p
forall a. Num a => a -> a -> a
- p
1)
where
k :: Int
k = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy k -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy k
forall k (t :: k). Proxy t
Proxy :: Proxy k)) :: Int
(p
q, p
r) = p -> p -> (p, p)
forall a. Integral a => a -> a -> (a, a)
quotRem p
x (p
10 p -> Int -> p
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
k)
{-# INLINABLE roundDown #-}
data RoundToZero
type Truncate = RoundToZero
instance Round RoundToZero Integer where
roundDecimal :: Decimal RoundToZero (n + k) Integer
-> Decimal RoundToZero n Integer
roundDecimal = Decimal RoundToZero (n + k) Integer
-> Decimal RoundToZero n Integer
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundToZero
instance Round RoundToZero Int where
roundDecimal :: Decimal RoundToZero (n + k) Int -> Decimal RoundToZero n Int
roundDecimal = Decimal RoundToZero (n + k) Int -> Decimal RoundToZero n Int
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundToZero Int8 where
roundDecimal :: Decimal RoundToZero (n + k) Int8 -> Decimal RoundToZero n Int8
roundDecimal = Decimal RoundToZero (n + k) Int8 -> Decimal RoundToZero n Int8
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundToZero Int16 where
roundDecimal :: Decimal RoundToZero (n + k) Int16 -> Decimal RoundToZero n Int16
roundDecimal = Decimal RoundToZero (n + k) Int16 -> Decimal RoundToZero n Int16
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundToZero Int32 where
roundDecimal :: Decimal RoundToZero (n + k) Int32 -> Decimal RoundToZero n Int32
roundDecimal = Decimal RoundToZero (n + k) Int32 -> Decimal RoundToZero n Int32
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundToZero Int64 where
roundDecimal :: Decimal RoundToZero (n + k) Int64 -> Decimal RoundToZero n Int64
roundDecimal = Decimal RoundToZero (n + k) Int64 -> Decimal RoundToZero n Int64
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundToZero Word where
roundDecimal :: Decimal RoundToZero (n + k) Word -> Decimal RoundToZero n Word
roundDecimal = Decimal RoundToZero (n + k) Word -> Decimal RoundToZero n Word
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundToZero Word8 where
roundDecimal :: Decimal RoundToZero (n + k) Word8 -> Decimal RoundToZero n Word8
roundDecimal = Decimal RoundToZero (n + k) Word8 -> Decimal RoundToZero n Word8
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundToZero Word16 where
roundDecimal :: Decimal RoundToZero (n + k) Word16 -> Decimal RoundToZero n Word16
roundDecimal = Decimal RoundToZero (n + k) Word16 -> Decimal RoundToZero n Word16
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundToZero Word32 where
roundDecimal :: Decimal RoundToZero (n + k) Word32 -> Decimal RoundToZero n Word32
roundDecimal = Decimal RoundToZero (n + k) Word32 -> Decimal RoundToZero n Word32
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundToZero
{-# INLINABLE roundDecimal #-}
instance Round RoundToZero Word64 where
roundDecimal :: Decimal RoundToZero (n + k) Word64 -> Decimal RoundToZero n Word64
roundDecimal = Decimal RoundToZero (n + k) Word64 -> Decimal RoundToZero n Word64
forall r (n :: Nat) (k :: Nat) p.
(Integral p, KnownNat k) =>
Decimal r (n + k) p -> Decimal r n p
roundToZero
{-# INLINABLE roundDecimal #-}
roundToZero :: forall r n k p . (Integral p, KnownNat k) => Decimal r (n + k) p -> Decimal r n p
roundToZero :: Decimal r (n + k) p -> Decimal r n p
roundToZero (Decimal p
x) = p -> Decimal r n p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (p -> p -> p
forall a. Integral a => a -> a -> a
quot p
x (p
10 p -> Int -> p
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
k))
where
k :: Int
k = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy k -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy k
forall k (t :: k). Proxy t
Proxy :: Proxy k)) :: Int
{-# INLINABLE roundToZero #-}
decimalList :: Integral p => [p] -> [Decimal r s p]
decimalList :: [p] -> [Decimal r s p]
decimalList = [p] -> [Decimal r s p]
coerce
sumDecimalBounded ::
(MonadThrow m, Foldable f, Eq p, Ord p, Num p, Bounded p)
=> f (Decimal r s p)
-> m (Decimal r s p)
sumDecimalBounded :: f (Decimal r s p) -> m (Decimal r s p)
sumDecimalBounded = (Decimal r s p -> Decimal r s p -> m (Decimal r s p))
-> Decimal r s p -> f (Decimal r s p) -> m (Decimal r s p)
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM Decimal r s p -> Decimal r s p -> m (Decimal r s p)
forall (m :: * -> *) p r (s :: Nat).
(MonadThrow m, Eq p, Ord p, Num p, Bounded p) =>
Decimal r s p -> Decimal r s p -> m (Decimal r s p)
plusDecimalBounded (p -> Decimal r s p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal p
0)
{-# INLINABLE sumDecimalBounded #-}
productDecimalBoundedWithRounding ::
(MonadThrow m, Foldable f, KnownNat s, Round r Integer, Integral p, Bounded p)
=> f (Decimal r s p)
-> m (Decimal r s p)
productDecimalBoundedWithRounding :: f (Decimal r s p) -> m (Decimal r s p)
productDecimalBoundedWithRounding f (Decimal r s p)
ds =
p -> m (Decimal r s p)
forall p (s :: Nat) (m :: * -> *) r.
(Integral p, Bounded p, KnownNat s, MonadThrow m) =>
p -> m (Decimal r s p)
fromIntegralDecimalBounded p
1 m (Decimal r s p)
-> (Decimal r s p -> m (Decimal r s p)) -> m (Decimal r s p)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
(\Decimal r s p
acc -> (Decimal r s p -> Decimal r s p -> m (Decimal r s p))
-> Decimal r s p -> f (Decimal r s p) -> m (Decimal r s p)
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM Decimal r s p -> Decimal r s p -> m (Decimal r s p)
forall (m :: * -> *) (s :: Nat) r p.
(MonadThrow m, KnownNat s, Round r Integer, Integral p,
Bounded p) =>
Decimal r s p -> Decimal r s p -> m (Decimal r s p)
timesDecimalBoundedWithRounding Decimal r s p
acc f (Decimal r s p)
ds)
{-# INLINABLE productDecimalBoundedWithRounding #-}
toScientificDecimal :: (Integral p, KnownNat s) => Decimal r s p -> Scientific
toScientificDecimal :: Decimal r s p -> Scientific
toScientificDecimal Decimal r s p
dec =
Integer -> Int -> Scientific
scientific
(p -> Integer
forall a. Integral a => a -> Integer
toInteger (Decimal r s p -> p
forall r (s :: Nat) p. Decimal r s p -> p
unwrapDecimal Decimal r s p
dec))
(Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Integer
forall a. Num a => a -> a
negate (Decimal r s p -> Integer
forall r (s :: Nat) p. KnownNat s => Decimal r s p -> Integer
getScale Decimal r s p
dec)))
fromScientificDecimal ::
forall m r s. (MonadThrow m, KnownNat s)
=> Scientific
-> m (Decimal r s Integer)
fromScientificDecimal :: Scientific -> m (Decimal r s Integer)
fromScientificDecimal Scientific
numNonNormal
| Integer
exp10 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
s = ArithException -> m (Decimal r s Integer)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM ArithException
Underflow
| Bool
otherwise = Decimal r s Integer -> m (Decimal r s Integer)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer -> Decimal r s Integer
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (Scientific -> Integer
coefficient Scientific
num Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
10 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (Integer
s Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
exp10)))
where
num :: Scientific
num = Scientific -> Scientific
normalize Scientific
numNonNormal
s :: Integer
s = Proxy s -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy s
forall k (t :: k). Proxy t
Proxy :: Proxy s)
exp10 :: Integer
exp10 = Integer -> Integer
forall a. Num a => a -> a
negate (Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Scientific -> Int
base10Exponent Scientific
num))
fromScientificDecimalBounded ::
forall m r s p. (MonadThrow m, Integral p, Bounded p, KnownNat s)
=> Scientific
-> m (Decimal r s p)
fromScientificDecimalBounded :: Scientific -> m (Decimal r s p)
fromScientificDecimalBounded Scientific
numNonNormal = do
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer
coeff Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< p -> Integer
forall a. Integral a => a -> Integer
toInteger (p
forall a. Bounded a => a
minBound :: p) Bool -> Bool -> Bool
|| Integer
exp10 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
s) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ ArithException -> m ()
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM ArithException
Underflow
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer
coeff Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
imax Bool -> Bool -> Bool
|| Integer
posExp10 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
upperExponentBound Bool -> Bool -> Bool
|| Integer
scaledCoeff Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
imax) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ ArithException -> m ()
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM ArithException
Overflow
Decimal r s p -> m (Decimal r s p)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (p -> Decimal r s p
forall r (s :: Nat) p. p -> Decimal r s p
Decimal (Integer -> p
forall a. Num a => Integer -> a
fromInteger Integer
scaledCoeff))
where
num :: Scientific
num = Scientific -> Scientific
normalize Scientific
numNonNormal
s :: Integer
s = Proxy s -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy s
forall k (t :: k). Proxy t
Proxy :: Proxy s)
posExp10 :: Integer
posExp10 = Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Scientific -> Int
base10Exponent Scientific
num)
exp10 :: Integer
exp10 = Integer -> Integer
forall a. Num a => a -> a
negate Integer
posExp10
imax :: Integer
imax = p -> Integer
forall a. Integral a => a -> Integer
toInteger (p
forall a. Bounded a => a
maxBound :: p)
coeff :: Integer
coeff = Scientific -> Integer
coefficient Scientific
num
scaledCoeff :: Integer
scaledCoeff = Scientific -> Integer
coefficient Scientific
num Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
10 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (Integer
s Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
exp10)
upperExponentBound :: Integer
upperExponentBound = Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> Double -> Double
forall a. Floating a => a -> a -> a
logBase Double
10 (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ p -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (p
forall a. Bounded a => a
maxBound :: p) :: Double) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
s
type family FixedScale e :: Nat
type instance FixedScale E0 = 0
type instance FixedScale E1 = 1
type instance FixedScale E2 = 2
type instance FixedScale E3 = 3
type instance FixedScale E6 = 6
type instance FixedScale E9 = 9
type instance FixedScale E12 = 12
toFixedDecimal :: (s ~ FixedScale e, Integral p) => Decimal r s p -> Fixed e
toFixedDecimal :: Decimal r s p -> Fixed e
toFixedDecimal = Integer -> Fixed e
forall k (a :: k). Integer -> Fixed a
MkFixed (Integer -> Fixed e)
-> (Decimal r s p -> Integer) -> Decimal r s p -> Fixed e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p -> Integer
forall a. Integral a => a -> Integer
toInteger (p -> Integer) -> (Decimal r s p -> p) -> Decimal r s p -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Decimal r s p -> p
forall r (s :: Nat) p. Decimal r s p -> p
unwrapDecimal
fromFixedDecimal :: s ~ FixedScale e => Fixed e -> Decimal r s Integer
fromFixedDecimal :: Fixed e -> Decimal r s Integer
fromFixedDecimal = Fixed e -> Decimal r s Integer
coerce
fromFixedDecimalBounded ::
(s ~ FixedScale e, MonadThrow m, Integral p, Bounded p)
=> Fixed e
-> m (Decimal r s p)
fromFixedDecimalBounded :: Fixed e -> m (Decimal r s p)
fromFixedDecimalBounded = Decimal r s Integer -> m (Decimal r s p)
forall (m :: * -> *) r (s :: Nat) p.
(MonadThrow m, Integral p, Bounded p) =>
Decimal r s Integer -> m (Decimal r s p)
fromIntegerDecimalBounded (Decimal r s Integer -> m (Decimal r s p))
-> (Fixed e -> Decimal r s Integer) -> Fixed e -> m (Decimal r s p)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fixed e -> Decimal r s Integer
forall (s :: Nat) e r.
(s ~ FixedScale e) =>
Fixed e -> Decimal r s Integer
fromFixedDecimal