{-# LANGUAGE GeneralizedNewtypeDeriving #-}

-----------------------------------------------------------------------------
-- |
-- Copyright   :  (c) Edward Kmett 2010-2021
-- License     :  BSD3
-- Maintainer  :  ekmett@gmail.com
-- Stability   :  experimental
-- Portability :  GHC only
--
-- A version of 'Double' that rounds to the twelfth digit if necessary. This
-- is useful for @ad@'s doctests since they must print out floating-point
-- numbers in their entirety, but the actual numbers that get produced can
-- vary slightly depending on machine-specific implementation details.
-- (See #73 for an example.) This works around the issue by just rounding
-- up the printed result to a point where it should be consistent across
-- all machines.
-----------------------------------------------------------------------------
module Numeric.AD.Internal.Doctest (RDouble) where

import GHC.Float
import Numeric

newtype RDouble = RDouble Double
  deriving (Fractional RDouble
RDouble
Fractional RDouble
-> RDouble
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble -> RDouble)
-> (RDouble -> RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> Floating RDouble
RDouble -> RDouble
RDouble -> RDouble -> RDouble
forall a.
Fractional a
-> a
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> Floating a
log1mexp :: RDouble -> RDouble
$clog1mexp :: RDouble -> RDouble
log1pexp :: RDouble -> RDouble
$clog1pexp :: RDouble -> RDouble
expm1 :: RDouble -> RDouble
$cexpm1 :: RDouble -> RDouble
log1p :: RDouble -> RDouble
$clog1p :: RDouble -> RDouble
atanh :: RDouble -> RDouble
$catanh :: RDouble -> RDouble
acosh :: RDouble -> RDouble
$cacosh :: RDouble -> RDouble
asinh :: RDouble -> RDouble
$casinh :: RDouble -> RDouble
tanh :: RDouble -> RDouble
$ctanh :: RDouble -> RDouble
cosh :: RDouble -> RDouble
$ccosh :: RDouble -> RDouble
sinh :: RDouble -> RDouble
$csinh :: RDouble -> RDouble
atan :: RDouble -> RDouble
$catan :: RDouble -> RDouble
acos :: RDouble -> RDouble
$cacos :: RDouble -> RDouble
asin :: RDouble -> RDouble
$casin :: RDouble -> RDouble
tan :: RDouble -> RDouble
$ctan :: RDouble -> RDouble
cos :: RDouble -> RDouble
$ccos :: RDouble -> RDouble
sin :: RDouble -> RDouble
$csin :: RDouble -> RDouble
logBase :: RDouble -> RDouble -> RDouble
$clogBase :: RDouble -> RDouble -> RDouble
** :: RDouble -> RDouble -> RDouble
$c** :: RDouble -> RDouble -> RDouble
sqrt :: RDouble -> RDouble
$csqrt :: RDouble -> RDouble
log :: RDouble -> RDouble
$clog :: RDouble -> RDouble
exp :: RDouble -> RDouble
$cexp :: RDouble -> RDouble
pi :: RDouble
$cpi :: RDouble
$cp1Floating :: Fractional RDouble
Floating, Num RDouble
Num RDouble
-> (RDouble -> RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (Rational -> RDouble)
-> Fractional RDouble
Rational -> RDouble
RDouble -> RDouble
RDouble -> RDouble -> RDouble
forall a.
Num a
-> (a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
fromRational :: Rational -> RDouble
$cfromRational :: Rational -> RDouble
recip :: RDouble -> RDouble
$crecip :: RDouble -> RDouble
/ :: RDouble -> RDouble -> RDouble
$c/ :: RDouble -> RDouble -> RDouble
$cp1Fractional :: Num RDouble
Fractional, Integer -> RDouble
RDouble -> RDouble
RDouble -> RDouble -> RDouble
(RDouble -> RDouble -> RDouble)
-> (RDouble -> RDouble -> RDouble)
-> (RDouble -> RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (RDouble -> RDouble)
-> (Integer -> RDouble)
-> Num RDouble
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> RDouble
$cfromInteger :: Integer -> RDouble
signum :: RDouble -> RDouble
$csignum :: RDouble -> RDouble
abs :: RDouble -> RDouble
$cabs :: RDouble -> RDouble
negate :: RDouble -> RDouble
$cnegate :: RDouble -> RDouble
* :: RDouble -> RDouble -> RDouble
$c* :: RDouble -> RDouble -> RDouble
- :: RDouble -> RDouble -> RDouble
$c- :: RDouble -> RDouble -> RDouble
+ :: RDouble -> RDouble -> RDouble
$c+ :: RDouble -> RDouble -> RDouble
Num)

instance Show RDouble where
  showsPrec :: Int -> RDouble -> ShowS
showsPrec Int
p (RDouble Double
d)
    | [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
is' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
limit
    = (Double -> ShowS) -> Int -> Double -> ShowS
forall a. RealFloat a => (a -> ShowS) -> Int -> a -> ShowS
showSignedFloat (Maybe Int -> Double -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showGFloat (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
limit)) Int
p Double
d
    | Bool
otherwise
    = Int -> Double -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
p Double
d
    where
      limit :: Int
limit = Int
12
      ([Int]
is, Int
e) = Integer -> Double -> ([Int], Int)
forall a. RealFloat a => Integer -> a -> ([Int], Int)
floatToDigits Integer
10 (Double -> Double
forall a. Num a => a -> a
abs Double
d)
      is' :: [Int]
is' = Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
drop Int
e [Int]
is