module Data.Number.BigFloat(
BigFloat,
Epsilon, Eps1, EpsDiv10, Prec10, Prec50, PrecPlus20
) where
import Numeric(showSigned)
import Data.Number.Fixed
import qualified Data.Number.FixedFunctions as F
base :: (Num a) => a
base :: forall a. Num a => a
base = a
10
data BigFloat e = BF (Fixed e) Integer
deriving (BigFloat e -> BigFloat e -> Bool
(BigFloat e -> BigFloat e -> Bool)
-> (BigFloat e -> BigFloat e -> Bool) -> Eq (BigFloat e)
forall e. BigFloat e -> BigFloat e -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BigFloat e -> BigFloat e -> Bool
$c/= :: forall e. BigFloat e -> BigFloat e -> Bool
== :: BigFloat e -> BigFloat e -> Bool
$c== :: forall e. BigFloat e -> BigFloat e -> Bool
Eq)
instance (Epsilon e) => Show (BigFloat e) where
showsPrec :: Int -> BigFloat e -> ShowS
showsPrec = (BigFloat e -> ShowS) -> Int -> BigFloat e -> ShowS
forall a. Real a => (a -> ShowS) -> Int -> a -> ShowS
showSigned BigFloat e -> ShowS
forall {e}. Epsilon e => BigFloat e -> ShowS
showBF
where showBF :: BigFloat e -> ShowS
showBF (BF Fixed e
m Integer
e) = Int -> Fixed e -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
0 Fixed e
m ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
"e" ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
0 Integer
e
instance (Epsilon e) => Num (BigFloat e) where
BF Fixed e
m1 Integer
e1 + :: BigFloat e -> BigFloat e -> BigFloat e
+ BF Fixed e
m2 Integer
e2 = Fixed e -> Integer -> BigFloat e
forall e. Epsilon e => Fixed e -> Integer -> BigFloat e
bf (Fixed e
m1' Fixed e -> Fixed e -> Fixed e
forall a. Num a => a -> a -> a
+ Fixed e
m2') Integer
e
where (Fixed e
m1', Fixed e
m2') = if Integer
e Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
e1 then (Fixed e
m1, Fixed e
m2 Fixed e -> Fixed e -> Fixed e
forall a. Fractional a => a -> a -> a
/ Fixed e
forall a. Num a => a
baseFixed e -> Integer -> Fixed e
forall a b. (Num a, Integral b) => a -> b -> a
^(Integer
eInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
e2))
else (Fixed e
m1 Fixed e -> Fixed e -> Fixed e
forall a. Fractional a => a -> a -> a
/ Fixed e
forall a. Num a => a
baseFixed e -> Integer -> Fixed e
forall a b. (Num a, Integral b) => a -> b -> a
^(Integer
eInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
e1), Fixed e
m2)
e :: Integer
e = Integer
e1 Integer -> Integer -> Integer
forall a. Ord a => a -> a -> a
`max` Integer
e2
BF Fixed e
m1 Integer
e1 * :: BigFloat e -> BigFloat e -> BigFloat e
* BF Fixed e
m2 Integer
e2 = Fixed e -> Integer -> BigFloat e
forall e. Epsilon e => Fixed e -> Integer -> BigFloat e
bf (Fixed e
m1 Fixed e -> Fixed e -> Fixed e
forall a. Num a => a -> a -> a
* Fixed e
m2) (Integer
e1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
e2)
negate :: BigFloat e -> BigFloat e
negate (BF Fixed e
m Integer
e) = Fixed e -> Integer -> BigFloat e
forall e. Fixed e -> Integer -> BigFloat e
BF (-Fixed e
m) Integer
e
abs :: BigFloat e -> BigFloat e
abs (BF Fixed e
m Integer
e) = Fixed e -> Integer -> BigFloat e
forall e. Fixed e -> Integer -> BigFloat e
BF (Fixed e -> Fixed e
forall a. Num a => a -> a
abs Fixed e
m) Integer
e
signum :: BigFloat e -> BigFloat e
signum (BF Fixed e
m Integer
_) = Fixed e -> Integer -> BigFloat e
forall e. Epsilon e => Fixed e -> Integer -> BigFloat e
bf (Fixed e -> Fixed e
forall a. Num a => a -> a
signum Fixed e
m) Integer
0
fromInteger :: Integer -> BigFloat e
fromInteger Integer
i = Fixed e -> Integer -> BigFloat e
forall e. Epsilon e => Fixed e -> Integer -> BigFloat e
bf (Integer -> Fixed e
forall a. Num a => Integer -> a
fromInteger Integer
i) Integer
0
instance (Epsilon e) => Real (BigFloat e) where
toRational :: BigFloat e -> Rational
toRational (BF Fixed e
e Integer
m) = Fixed e -> Rational
forall a. Real a => a -> Rational
toRational Fixed e
e Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
forall a. Num a => a
baseRational -> Integer -> Rational
forall a b. (Fractional a, Integral b) => a -> b -> a
^^Integer
m
instance (Epsilon e) => Ord (BigFloat e) where
compare :: BigFloat e -> BigFloat e -> Ordering
compare BigFloat e
x BigFloat e
y = Rational -> Rational -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (BigFloat e -> Rational
forall a. Real a => a -> Rational
toRational BigFloat e
x) (BigFloat e -> Rational
forall a. Real a => a -> Rational
toRational BigFloat e
y)
instance (Epsilon e) => Fractional (BigFloat e) where
recip :: BigFloat e -> BigFloat e
recip (BF Fixed e
m Integer
e) = Fixed e -> Integer -> BigFloat e
forall e. Epsilon e => Fixed e -> Integer -> BigFloat e
bf (Fixed e
forall a. Num a => a
base Fixed e -> Fixed e -> Fixed e
forall a. Fractional a => a -> a -> a
/ Fixed e
m) (-(Integer
e Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1))
fromRational :: Rational -> BigFloat e
fromRational Rational
x
| Rational
x Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
== Rational
0 Bool -> Bool -> Bool
|| Rational -> Rational
forall a. Num a => a -> a
abs Rational
x Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
>= Rational
1 = Fixed e -> Integer -> BigFloat e
forall e. Epsilon e => Fixed e -> Integer -> BigFloat e
bf (Rational -> Fixed e
forall a. Fractional a => Rational -> a
fromRational Rational
x) Integer
0
| Bool
otherwise = BigFloat e -> BigFloat e
forall a. Fractional a => a -> a
recip (BigFloat e -> BigFloat e) -> BigFloat e -> BigFloat e
forall a b. (a -> b) -> a -> b
$ Fixed e -> Integer -> BigFloat e
forall e. Epsilon e => Fixed e -> Integer -> BigFloat e
bf (Rational -> Fixed e
forall a. Fractional a => Rational -> a
fromRational (Rational -> Rational
forall a. Fractional a => a -> a
recip Rational
x)) Integer
0
bf :: (Epsilon e) => Fixed e -> Integer -> BigFloat e
bf :: forall e. Epsilon e => Fixed e -> Integer -> BigFloat e
bf Fixed e
m Integer
e | Fixed e
m Fixed e -> Fixed e -> Bool
forall a. Eq a => a -> a -> Bool
== Fixed e
0 = Fixed e -> Integer -> BigFloat e
forall e. Fixed e -> Integer -> BigFloat e
BF Fixed e
0 Integer
0
| Fixed e
m Fixed e -> Fixed e -> Bool
forall a. Ord a => a -> a -> Bool
< Fixed e
0 = - Fixed e -> Integer -> BigFloat e
forall e. Epsilon e => Fixed e -> Integer -> BigFloat e
bf (-Fixed e
m) Integer
e
| Fixed e
m Fixed e -> Fixed e -> Bool
forall a. Ord a => a -> a -> Bool
>= Fixed e
forall a. Num a => a
base = Fixed e -> Integer -> BigFloat e
forall e. Epsilon e => Fixed e -> Integer -> BigFloat e
bf (Fixed e
m Fixed e -> Fixed e -> Fixed e
forall a. Fractional a => a -> a -> a
/ Fixed e
forall a. Num a => a
base) (Integer
e Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1)
| Fixed e
m Fixed e -> Fixed e -> Bool
forall a. Ord a => a -> a -> Bool
< Fixed e
1 = Fixed e -> Integer -> BigFloat e
forall e. Epsilon e => Fixed e -> Integer -> BigFloat e
bf (Fixed e
m Fixed e -> Fixed e -> Fixed e
forall a. Num a => a -> a -> a
* Fixed e
forall a. Num a => a
base) (Integer
e Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1)
| Bool
otherwise = Fixed e -> Integer -> BigFloat e
forall e. Fixed e -> Integer -> BigFloat e
BF Fixed e
m Integer
e
instance (Epsilon e) => RealFrac (BigFloat e) where
properFraction :: forall b. Integral b => BigFloat e -> (b, BigFloat e)
properFraction x :: BigFloat e
x@(BF Fixed e
m Integer
e) =
if Integer
e Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 then (b
0, BigFloat e
x)
else let (b
i, Fixed e
f) = Fixed e -> (b, Fixed e)
forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction (Fixed e
m Fixed e -> Fixed e -> Fixed e
forall a. Num a => a -> a -> a
* Fixed e
forall a. Num a => a
baseFixed e -> Integer -> Fixed e
forall a b. (Fractional a, Integral b) => a -> b -> a
^^Integer
e)
in (b
i, Fixed e -> Integer -> BigFloat e
forall e. Epsilon e => Fixed e -> Integer -> BigFloat e
bf Fixed e
f Integer
0)
instance (Epsilon e) => Floating (BigFloat e) where
pi :: BigFloat e
pi = Fixed e -> Integer -> BigFloat e
forall e. Epsilon e => Fixed e -> Integer -> BigFloat e
bf Fixed e
forall a. Floating a => a
pi Integer
0
sqrt :: BigFloat e -> BigFloat e
sqrt = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.sqrt
exp :: BigFloat e -> BigFloat e
exp = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.exp
log :: BigFloat e -> BigFloat e
log = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.log
sin :: BigFloat e -> BigFloat e
sin = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.sin
cos :: BigFloat e -> BigFloat e
cos = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.cos
tan :: BigFloat e -> BigFloat e
tan = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.tan
asin :: BigFloat e -> BigFloat e
asin = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.asin
acos :: BigFloat e -> BigFloat e
acos = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.acos
atan :: BigFloat e -> BigFloat e
atan = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.atan
sinh :: BigFloat e -> BigFloat e
sinh = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.sinh
cosh :: BigFloat e -> BigFloat e
cosh = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.cosh
tanh :: BigFloat e -> BigFloat e
tanh = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.tanh
asinh :: BigFloat e -> BigFloat e
asinh = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.asinh
acosh :: BigFloat e -> BigFloat e
acosh = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.acosh
atanh :: BigFloat e -> BigFloat e
atanh = (Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
F.atanh
instance (Epsilon e) => RealFloat (BigFloat e) where
floatRadix :: BigFloat e -> Integer
floatRadix BigFloat e
_ = Integer
forall a. Num a => a
base
floatDigits :: BigFloat e -> Int
floatDigits (BF Fixed e
m Integer
_) =
Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (Double -> Int) -> Double -> Int
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
forall a. Floating a => a -> a -> a
logBase Double
forall a. Num a => a
base (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Fractional a => a -> a
recip (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational (Rational -> Double) -> Rational -> Double
forall a b. (a -> b) -> a -> b
$ Fixed e -> Rational
forall e. Epsilon e => Fixed e -> Rational
precision Fixed e
m
floatRange :: BigFloat e -> (Int, Int)
floatRange BigFloat e
_ = (Int
forall a. Bounded a => a
minBound, Int
forall a. Bounded a => a
maxBound)
decodeFloat :: BigFloat e -> (Integer, Int)
decodeFloat x :: BigFloat e
x@(BF Fixed e
m Integer
e) =
let d :: Int
d = BigFloat e -> Int
forall a. RealFloat a => a -> Int
floatDigits BigFloat e
x
in (Fixed e -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round (Fixed e -> Integer) -> Fixed e -> Integer
forall a b. (a -> b) -> a -> b
$ Fixed e
m Fixed e -> Fixed e -> Fixed e
forall a. Num a => a -> a -> a
* Fixed e
forall a. Num a => a
baseFixed e -> Int -> Fixed e
forall a b. (Num a, Integral b) => a -> b -> a
^Int
d, Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
e Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
d)
encodeFloat :: Integer -> Int -> BigFloat e
encodeFloat Integer
m Int
e = Fixed e -> Integer -> BigFloat e
forall e. Epsilon e => Fixed e -> Integer -> BigFloat e
bf (Integer -> Fixed e
forall a. Num a => Integer -> a
fromInteger Integer
m) (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
e)
exponent :: BigFloat e -> Int
exponent (BF Fixed e
_ Integer
e) = Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
e
significand :: BigFloat e -> BigFloat e
significand (BF Fixed e
m Integer
_) = Fixed e -> Integer -> BigFloat e
forall e. Fixed e -> Integer -> BigFloat e
BF Fixed e
m Integer
0
scaleFloat :: Int -> BigFloat e -> BigFloat e
scaleFloat Int
n (BF Fixed e
m Integer
e) = Fixed e -> Integer -> BigFloat e
forall e. Fixed e -> Integer -> BigFloat e
BF Fixed e
m (Integer
e Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
n)
isNaN :: BigFloat e -> Bool
isNaN BigFloat e
_ = Bool
False
isInfinite :: BigFloat e -> Bool
isInfinite BigFloat e
_ = Bool
False
isDenormalized :: BigFloat e -> Bool
isDenormalized BigFloat e
_ = Bool
False
isNegativeZero :: BigFloat e -> Bool
isNegativeZero BigFloat e
_ = Bool
False
isIEEE :: BigFloat e -> Bool
isIEEE BigFloat e
_ = Bool
False
toFloat1 :: (Epsilon e) => (Rational -> Rational -> Rational) ->
BigFloat e -> BigFloat e
toFloat1 :: forall e.
Epsilon e =>
(Rational -> Rational -> Rational) -> BigFloat e -> BigFloat e
toFloat1 Rational -> Rational -> Rational
f x :: BigFloat e
x@(BF Fixed e
m Integer
e) =
Rational -> BigFloat e
forall a. Fractional a => Rational -> a
fromRational (Rational -> BigFloat e) -> Rational -> BigFloat e
forall a b. (a -> b) -> a -> b
$ Rational -> Rational -> Rational
f (Fixed e -> Rational
forall e. Epsilon e => Fixed e -> Rational
precision Fixed e
m Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
scl) (Fixed e -> Rational
forall a. Real a => a -> Rational
toRational Fixed e
m Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
scl)
where scl :: Rational
scl = Rational
forall a. Num a => a
baseRational -> Integer -> Rational
forall a b. (Fractional a, Integral b) => a -> b -> a
^^Integer
e