{-|
    Module      :  AERN2.MP.Float
    Description :  Arbitrary precision floating point numbers
    Copyright   :  (c) Michal Konecny
    License     :  BSD3

    Maintainer  :  mikkonecny@gmail.com
    Stability   :  experimental
    Portability :  portable

    Arbitrary precision floating-point numbers with up/down-rounded operations.
-}

module AERN2.MP.Float
  (
   -- * Precision operations
   module Precision
   -- * Helper structure
   , module Auxi
   -- * The type definition and basic operations
   , module Type
   -- * Arithmetic operations
   , module Arithmetic
   , distUp, distDown, avgUp, avgDown
   -- * Conversions, comparisons and norm, constants such as NaN, infinity
   , module Conversions
   -- * Infix operators for up/down-rounded operations
   , module Operators
   -- * Tests
   , module Tests
   )
where

import MixedTypesNumPrelude
-- import qualified Prelude as P

import AERN2.MP.Precision as Precision
import AERN2.MP.Float.Auxi as Auxi

import AERN2.MP.Float.Type as Type
import AERN2.MP.Float.Arithmetic as Arithmetic
import AERN2.MP.Float.Conversions as Conversions

import AERN2.MP.Float.Operators as Operators
import AERN2.MP.Float.Tests as Tests

-- | Computes an upper bound to the distance @|x - y|@ of @x@ and @y@.
distUp :: MPFloat -> MPFloat -> MPFloat
distUp :: MPFloat -> MPFloat -> MPFloat
distUp MPFloat
x MPFloat
y = if MPFloat
x MPFloat -> MPFloat -> OrderCompareType MPFloat MPFloat
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
>= MPFloat
y then MPFloat
x MPFloat -> MPFloat -> MPFloat
-^ MPFloat
y else MPFloat
y MPFloat -> MPFloat -> MPFloat
-^ MPFloat
x

-- | Computes a lower bound to the distance @|x - y|@ of @x@ and @y@.
distDown :: MPFloat -> MPFloat -> MPFloat
distDown :: MPFloat -> MPFloat -> MPFloat
distDown MPFloat
x MPFloat
y = if MPFloat
x MPFloat -> MPFloat -> OrderCompareType MPFloat MPFloat
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
>= MPFloat
y then MPFloat
x MPFloat -> MPFloat -> MPFloat
-. MPFloat
y else MPFloat
y MPFloat -> MPFloat -> MPFloat
-. MPFloat
x

avgUp :: MPFloat -> MPFloat -> MPFloat
avgUp :: MPFloat -> MPFloat -> MPFloat
avgUp MPFloat
x MPFloat
y = (MPFloat
x MPFloat -> MPFloat -> MPFloat
+^ MPFloat
y) MPFloat -> MPFloat -> MPFloat
/^ (Integer -> MPFloat
forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
2)

avgDown :: MPFloat -> MPFloat -> MPFloat
avgDown :: MPFloat -> MPFloat -> MPFloat
avgDown MPFloat
x MPFloat
y = (MPFloat
x MPFloat -> MPFloat -> MPFloat
+. MPFloat
y) MPFloat -> MPFloat -> MPFloat
/. (Integer -> MPFloat
forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
2)