- floatRadix :: a -> Integer
- floatDigits :: a -> Int
- floatRange :: a -> (Int,Int)
- decodeFloat :: a -> (Integer,Int)
- encodeFloat :: Integer -> Int -> a
- exponent :: a -> Int
- significand :: a -> a
- scaleFloat :: Int -> a -> a
- isNaN, isInfinite, isDenormalized, isNegativeZero, isIEEE
- :: a -> Bool
- atan2 :: a -> a -> a
-
-
- exponent x = if m == 0 then 0 else n + floatDigits x
- where (m,n) = decodeFloat x
-
- significand x = encodeFloat m (negate (floatDigits x))
- where (m,_) = decodeFloat x
-
- scaleFloat k x = encodeFloat m (n+k)
- where (m,n) = decodeFloat x
-
+ -- | a constant function, returning the radix of the representation
+ -- (often @2@)
+ floatRadix :: a -> Integer
+ -- | a constant function, returning the number of digits of
+ -- 'floatRadix' in the significand
+ floatDigits :: a -> Int
+ -- | a constant function, returning the lowest and highest values
+ -- the exponent may assume
+ floatRange :: a -> (Int,Int)
+ -- | The function 'decodeFloat' applied to a real floating-point
+ -- number returns the significand expressed as an 'Integer' and an
+ -- appropriately scaled exponent (an 'Int'). If @'decodeFloat' x@
+ -- yields @(m,n)@, then @x@ is equal in value to @m*b^^n@, where @b@
+ -- is the floating-point radix, and furthermore, either @m@ and @n@
+ -- are both zero or else @b^(d-1) <= m < b^d@, where @d@ is the value
+ -- of @'floatDigits' x@. In particular, @'decodeFloat' 0 = (0,0)@.
+ decodeFloat :: a -> (Integer,Int)
+ -- | 'encodeFloat' performs the inverse of 'decodeFloat'
+ encodeFloat :: Integer -> Int -> a
+ -- | the second component of 'decodeFloat'.
+ exponent :: a -> Int
+ -- | the first component of 'decodeFloat', scaled to lie in the open
+ -- interval (@-1@,@1@)
+ significand :: a -> a
+ -- | multiplies a floating-point number by an integer power of the radix
+ scaleFloat :: Int -> a -> a
+ -- | 'True' if the argument is an IEEE \"not-a-number\" (NaN) value
+ isNaN :: a -> Bool
+ -- | 'True' if the argument is an IEEE infinity or negative infinity
+ isInfinite :: a -> Bool
+ -- | 'True' if the argument is too small to be represented in
+ -- normalized format
+ isDenormalized :: a -> Bool
+ -- | 'True' if the argument is an IEEE negative zero
+ isNegativeZero :: a -> Bool
+ -- | 'True' if the argument is an IEEE floating point number
+ isIEEE :: a -> Bool
+ -- | a version of arctangent taking two real floating-point arguments.
+ -- For real floating @x@ and @y@, @'atan2' y x@ computes the angle
+ -- (from the positive x-axis) of the vector from the origin to the
+ -- point @(x,y)@. @'atan2' y x@ returns a value in the range [@-pi@,
+ -- @pi@]. It follows the Common Lisp semantics for the origin when
+ -- signed zeroes are supported. @'atan2' y 1@, with @y@ in a type
+ -- that is 'RealFloat', should return the same value as @'atan' y@.
+ -- A default definition of 'atan2' is provided, but implementors
+ -- can provide a more accurate implementation.
+ atan2 :: a -> a -> a
+
+
+ exponent x = if m == 0 then 0 else n + floatDigits x
+ where (m,n) = decodeFloat x
+
+ significand x = encodeFloat m (negate (floatDigits x))
+ where (m,_) = decodeFloat x
+
+ scaleFloat k x = encodeFloat m (n + clamp b k)
+ where (m,n) = decodeFloat x
+ (l,h) = floatRange x
+ d = floatDigits x
+ b = h - l + 4*d
+ -- n+k may overflow, which would lead
+ -- to wrong results, hence we clamp the
+ -- scaling parameter.
+ -- If n + k would be larger than h,
+ -- n + clamp b k must be too, simliar
+ -- for smaller than l - d.
+ -- Add a little extra to keep clear
+ -- from the boundary cases.
+