@@ -2,7 +2,7 @@ module Test.Main where
22
33import Prelude
44
5−import Data.Fixed (class KnownPrecision, Fixed, PProxy, fromNumber, toNumber, fromString, reifyPrecision, reflectPrecision, toString, P100)
5+import Data.Fixed (class KnownPrecision, Fixed, PProxy, fromNumber, toNumber, fromString, reifyPrecision, reflectPrecision, toString, P100, rescale, fromBigInt, floor)
66import Data.BigInt as BigInt
77import Data.Maybe (Maybe(..), fromJust, isJust)
88import Effect (Effect)
@@ -27,6 +27,28 @@ fromNumberWith
2727 -> Maybe (Fixed precision)
2828fromNumberWith _ = fromNumber
2929
30+-- | For type hinting.
31+withPrecisionOf
32+ :: forall precision
33+ . PProxy precision
34+ -> Fixed precision
35+ -> Fixed precision
36+withPrecisionOf _ x = x
37+
38+floorToPrecision
39+ :: forall precision
40+ . KnownPrecision precision
41+ => Int
42+ -> Fixed precision
43+ -> Fixed precision
44+floorToPrecision p =
45+ (_ / scaleFactor)
46+ <<< floor
47+ <<< (_ * scaleFactor)
48+ where
49+ scaleFactor =
50+ fromBigInt (BigInt.pow (BigInt.fromInt 10) (BigInt.fromInt p))
51+
3052main :: Effect Unit
3153main = do
3254 log "Commutative monoid under addition:"
@@ -123,3 +145,31 @@ main = do
123145 Nothing ->
124146 false
125147 <?> ("failed to roundtrip via Number: " <> show { precision, x })
148+
149+ log ""
150+ log "rescale"
151+ log ""
152+
153+ log "rescaling up then down should be no-op"
154+ quickCheck' 1000 do
155+ let lo = 10
156+ hi <- chooseInt 10 20
157+ unsafePartial fromJust $ join $
158+ reifyPrecision lo \lo_ ->
159+ reifyPrecision hi \hi_ -> do
160+ x <- genFixedP lo_
161+ let y = withPrecisionOf hi_ $ rescale x
162+ let xx = rescale y
163+ pure $ x == xx <?> show { x, xx, y }
164+
165+ log "rescaling down then up should be the same as flooring"
166+ quickCheck' 1000 do
167+ let hi = 20
168+ lo <- chooseInt 10 20
169+ unsafePartial fromJust $ join $
170+ reifyPrecision lo \lo_ ->
171+ reifyPrecision hi \hi_ -> do
172+ x <- genFixedP hi_
173+ let y = withPrecisionOf lo_ $ rescale x
174+ let xx = floorToPrecision lo x
175+ pure $ xx == rescale y <?> show { x, xx, y }