Skip to content

Instantly share code, notes, and snippets.

@ion1
Created September 2, 2011 07:47
Show Gist options
  • Save ion1/1188115 to your computer and use it in GitHub Desktop.
Save ion1/1188115 to your computer and use it in GitHub Desktop.
The minimum and maximum positive, finite floats
-- | The minimum and maximum positive, finite floats.
module FloatMinMax
( floatMin
, floatMaxDenorm
, floatMinNorm
, floatMax
)
where
import Data.Proxy
import Data.Tagged
-- | The minimum positive, denormalized float.
floatMin :: RealFloat a => a
floatMin = fixP $ \p -> let d = floatDigitsP p
(e,_) = floatRangeP p
in encodeFloat 1 (e-d)
{-# INLINE floatMin #-}
-- | The maximum denormalized float.
floatMaxDenorm :: RealFloat a => a
floatMaxDenorm = floatMinNorm - floatMin
{-# INLINE floatMaxDenorm #-}
-- | The minimum positive, normalized float.
floatMinNorm :: RealFloat a => a
floatMinNorm = fixP $ \p -> let (e,_) = floatRangeP p
in encodeFloat 1 (e-1)
{-# INLINE floatMinNorm #-}
-- | The maximum finite float.
floatMax :: RealFloat a => a
floatMax = fixP $ \p -> let r = floatRadixP p
d = floatDigitsP p
(_,e) = floatRangeP p
in encodeFloat (r^d-1) (e-d)
{-# INLINE floatMax #-}
-- | Like 'fix', but makes sure your function doesn't evaluate its parameter by
-- replacing it with a proxy. Use when you only want the parameter for its type
-- and recursion is undesired.
fixP :: (Proxy a -> a) -> a
fixP = untagSelf . unproxy
{-# INLINE fixP #-}
floatRadixP :: RealFloat a => Proxy a -> Integer
floatRadixP = floatRadix . (undefined `asProxyTypeOf`)
{-# INLINE floatRadixP #-}
floatDigitsP :: RealFloat a => Proxy a -> Int
floatDigitsP = floatDigits . (undefined `asProxyTypeOf`)
{-# INLINE floatDigitsP #-}
floatRangeP :: RealFloat a => Proxy a -> (Int, Int)
floatRangeP = floatRange . (undefined `asProxyTypeOf`)
{-# INLINE floatRangeP #-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment