module Data.Falsify.WordN (
WordN
, Precision(..)
, forgetPrecision
, zero
, truncateAt
, unsafeFromWord64
, toProperFraction
) where
import Data.Bits
import Data.Word
import Data.Falsify.ProperFraction (ProperFraction(..))
newtype Precision = Precision Word8
deriving stock (Int -> Precision -> ShowS
[Precision] -> ShowS
Precision -> String
(Int -> Precision -> ShowS)
-> (Precision -> String)
-> ([Precision] -> ShowS)
-> Show Precision
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Precision -> ShowS
showsPrec :: Int -> Precision -> ShowS
$cshow :: Precision -> String
show :: Precision -> String
$cshowList :: [Precision] -> ShowS
showList :: [Precision] -> ShowS
Show, Precision -> Precision -> Bool
(Precision -> Precision -> Bool)
-> (Precision -> Precision -> Bool) -> Eq Precision
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Precision -> Precision -> Bool
== :: Precision -> Precision -> Bool
$c/= :: Precision -> Precision -> Bool
/= :: Precision -> Precision -> Bool
Eq, Eq Precision
Eq Precision =>
(Precision -> Precision -> Ordering)
-> (Precision -> Precision -> Bool)
-> (Precision -> Precision -> Bool)
-> (Precision -> Precision -> Bool)
-> (Precision -> Precision -> Bool)
-> (Precision -> Precision -> Precision)
-> (Precision -> Precision -> Precision)
-> Ord Precision
Precision -> Precision -> Bool
Precision -> Precision -> Ordering
Precision -> Precision -> Precision
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Precision -> Precision -> Ordering
compare :: Precision -> Precision -> Ordering
$c< :: Precision -> Precision -> Bool
< :: Precision -> Precision -> Bool
$c<= :: Precision -> Precision -> Bool
<= :: Precision -> Precision -> Bool
$c> :: Precision -> Precision -> Bool
> :: Precision -> Precision -> Bool
$c>= :: Precision -> Precision -> Bool
>= :: Precision -> Precision -> Bool
$cmax :: Precision -> Precision -> Precision
max :: Precision -> Precision -> Precision
$cmin :: Precision -> Precision -> Precision
min :: Precision -> Precision -> Precision
Ord)
deriving newtype (Integer -> Precision
Precision -> Precision
Precision -> Precision -> Precision
(Precision -> Precision -> Precision)
-> (Precision -> Precision -> Precision)
-> (Precision -> Precision -> Precision)
-> (Precision -> Precision)
-> (Precision -> Precision)
-> (Precision -> Precision)
-> (Integer -> Precision)
-> Num Precision
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: Precision -> Precision -> Precision
+ :: Precision -> Precision -> Precision
$c- :: Precision -> Precision -> Precision
- :: Precision -> Precision -> Precision
$c* :: Precision -> Precision -> Precision
* :: Precision -> Precision -> Precision
$cnegate :: Precision -> Precision
negate :: Precision -> Precision
$cabs :: Precision -> Precision
abs :: Precision -> Precision
$csignum :: Precision -> Precision
signum :: Precision -> Precision
$cfromInteger :: Integer -> Precision
fromInteger :: Integer -> Precision
Num, Int -> Precision
Precision -> Int
Precision -> [Precision]
Precision -> Precision
Precision -> Precision -> [Precision]
Precision -> Precision -> Precision -> [Precision]
(Precision -> Precision)
-> (Precision -> Precision)
-> (Int -> Precision)
-> (Precision -> Int)
-> (Precision -> [Precision])
-> (Precision -> Precision -> [Precision])
-> (Precision -> Precision -> [Precision])
-> (Precision -> Precision -> Precision -> [Precision])
-> Enum Precision
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Precision -> Precision
succ :: Precision -> Precision
$cpred :: Precision -> Precision
pred :: Precision -> Precision
$ctoEnum :: Int -> Precision
toEnum :: Int -> Precision
$cfromEnum :: Precision -> Int
fromEnum :: Precision -> Int
$cenumFrom :: Precision -> [Precision]
enumFrom :: Precision -> [Precision]
$cenumFromThen :: Precision -> Precision -> [Precision]
enumFromThen :: Precision -> Precision -> [Precision]
$cenumFromTo :: Precision -> Precision -> [Precision]
enumFromTo :: Precision -> Precision -> [Precision]
$cenumFromThenTo :: Precision -> Precision -> Precision -> [Precision]
enumFromThenTo :: Precision -> Precision -> Precision -> [Precision]
Enum)
data WordN = WordN Precision Word64
deriving (Int -> WordN -> ShowS
[WordN] -> ShowS
WordN -> String
(Int -> WordN -> ShowS)
-> (WordN -> String) -> ([WordN] -> ShowS) -> Show WordN
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> WordN -> ShowS
showsPrec :: Int -> WordN -> ShowS
$cshow :: WordN -> String
show :: WordN -> String
$cshowList :: [WordN] -> ShowS
showList :: [WordN] -> ShowS
Show, WordN -> WordN -> Bool
(WordN -> WordN -> Bool) -> (WordN -> WordN -> Bool) -> Eq WordN
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: WordN -> WordN -> Bool
== :: WordN -> WordN -> Bool
$c/= :: WordN -> WordN -> Bool
/= :: WordN -> WordN -> Bool
Eq, Eq WordN
Eq WordN =>
(WordN -> WordN -> Ordering)
-> (WordN -> WordN -> Bool)
-> (WordN -> WordN -> Bool)
-> (WordN -> WordN -> Bool)
-> (WordN -> WordN -> Bool)
-> (WordN -> WordN -> WordN)
-> (WordN -> WordN -> WordN)
-> Ord WordN
WordN -> WordN -> Bool
WordN -> WordN -> Ordering
WordN -> WordN -> WordN
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: WordN -> WordN -> Ordering
compare :: WordN -> WordN -> Ordering
$c< :: WordN -> WordN -> Bool
< :: WordN -> WordN -> Bool
$c<= :: WordN -> WordN -> Bool
<= :: WordN -> WordN -> Bool
$c> :: WordN -> WordN -> Bool
> :: WordN -> WordN -> Bool
$c>= :: WordN -> WordN -> Bool
>= :: WordN -> WordN -> Bool
$cmax :: WordN -> WordN -> WordN
max :: WordN -> WordN -> WordN
$cmin :: WordN -> WordN -> WordN
min :: WordN -> WordN -> WordN
Ord)
forgetPrecision :: WordN -> Word64
forgetPrecision :: WordN -> Word64
forgetPrecision (WordN Precision
_ Word64
x) = Word64
x
zero :: Precision -> WordN
zero :: Precision -> WordN
zero Precision
p = Precision -> Word64 -> WordN
WordN Precision
p Word64
0
truncateAt :: Precision -> Word64 -> WordN
truncateAt :: Precision -> Word64 -> WordN
truncateAt Precision
desiredPrecision Word64
x =
Precision -> Word64 -> WordN
WordN Precision
actualPrecision (Word64
x Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Precision -> Word64
mask Precision
actualPrecision)
where
maximumPrecision, actualPrecision :: Precision
maximumPrecision :: Precision
maximumPrecision = Word8 -> Precision
Precision Word8
64
actualPrecision :: Precision
actualPrecision = Precision -> Precision -> Precision
forall a. Ord a => a -> a -> a
min Precision
desiredPrecision Precision
maximumPrecision
mask :: Precision -> Word64
mask :: Precision -> Word64
mask (Precision Word8
n) = Word64
2 Word64 -> Word8 -> Word64
forall a b. (Num a, Integral b) => a -> b -> a
^ Word8
n Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
1
unsafeFromWord64 :: Precision -> Word64 -> WordN
unsafeFromWord64 :: Precision -> Word64 -> WordN
unsafeFromWord64 = Precision -> Word64 -> WordN
WordN
toProperFraction :: WordN -> ProperFraction
toProperFraction :: WordN -> ProperFraction
toProperFraction (WordN (Precision Word8
p) Word64
x) =
Double -> ProperFraction
ProperFraction (Double -> ProperFraction) -> Double -> ProperFraction
forall a b. (a -> b) -> a -> b
$ (Word64 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
2 Double -> Word8 -> Double
forall a b. (Num a, Integral b) => a -> b -> a
^ Word8
p)