diff --git a/Data/ByteString/Builder/RealFloat.hs b/Data/ByteString/Builder/RealFloat.hs index 4a820b972..948fbc2cf 100644 --- a/Data/ByteString/Builder/RealFloat.hs +++ b/Data/ByteString/Builder/RealFloat.hs @@ -225,12 +225,14 @@ formatDouble = formatFloating {-# SPECIALIZE formatFloating :: FloatFormat -> Double -> Builder #-} formatFloating :: forall a mw ew ei. -- a + --( ToS a ( ToD a + , Num a + , Ord a , RealFloat a - , R.CastToWord a - , R.MantissaBits a , R.ExponentBits a - , Bits (R.ExponentWord a) + , R.MantissaBits a + , R.CastToWord a -- mantissa , mw ~ R.MantissaWord a , R.Mantissa mw @@ -238,28 +240,23 @@ formatFloating :: forall a mw ew ei. , R.DecimalLength mw -- exponent , ew ~ R.ExponentWord a - , Integral (R.ExponentWord a) + , Integral ew + , Bits ew , ei ~ R.ExponentInt a , R.ToInt ei , Integral ei , R.FromInt ei ) => FloatFormat -> a -> Builder formatFloating fmt f = case fmt of - FGeneric eE prec (minExpo,maxExpo) ss -> - case R.toCharsNonNumbersAndZero ss f of - Just b -> BP.primBounded b () - Nothing -> - if e' >= minExpo && e' <= maxExpo - then printSign f `mappend` showStandard (toWord64 m) e' prec - else BP.primBounded (sci eE) () - FScientific eE ss -> flip BP.primBounded () - $ fromMaybe (sci eE) (R.toCharsNonNumbersAndZero ss f) - FStandard prec ss -> - case R.toCharsNonNumbersAndZero ss f of - Just b -> BP.primBounded b () - Nothing -> printSign f `mappend` showStandard (toWord64 m) e' prec + FGeneric eE prec (minExpo,maxExpo) ss -> flip fromMaybe (R.toCharsNonNumbersAndZero ss f) $ + if e' >= minExpo && e' <= maxExpo + then printSign f `mappend` showStandard (toWord64 m) e' prec + else sci eE + FScientific eE ss -> fromMaybe (sci eE) (R.toCharsNonNumbersAndZero ss f) + FStandard prec ss -> flip fromMaybe (R.toCharsNonNumbersAndZero ss f) $ + printSign f `mappend` showStandard (toWord64 m) e' prec where - sci eE = R.toCharsScientific @a Proxy eE sign m e + sci eE = BP.primBounded (R.toCharsScientific @a Proxy eE sign m e) () e' = R.toInt e + R.decimalLength m R.FloatingDecimal m e = toD @a mantissa expo (sign, mantissa, expo) = R.breakdown f diff --git a/Data/ByteString/Builder/RealFloat/Internal.hs b/Data/ByteString/Builder/RealFloat/Internal.hs index 1e2e56bfe..acffac3e4 100644 --- a/Data/ByteString/Builder/RealFloat/Internal.hs +++ b/Data/ByteString/Builder/RealFloat/Internal.hs @@ -6,7 +6,6 @@ {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} -{-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE BlockArguments #-} @@ -89,9 +88,11 @@ module Data.ByteString.Builder.RealFloat.Internal import Control.Monad (foldM) import Data.Bits (Bits(..), FiniteBits(..)) import Data.ByteString.Internal (c2w) +import Data.ByteString.Builder.Internal (Builder) import Data.ByteString.Builder.Prim.Internal (BoundedPrim, boundedPrim) import Data.ByteString.Builder.RealFloat.TableGenerator import Data.ByteString.Utils.UnalignedWrite +import qualified Data.ByteString.Builder.Prim as BP import Data.Char (ord) import Data.Proxy (Proxy) import Foreign.C.Types @@ -265,19 +266,31 @@ boundString s = boundedPrim maxEncodedLength $ const (pokeAll s) -- * biased exponent = all 0 bits. -- * fraction = all 0 bits. {-# INLINABLE toCharsNonNumbersAndZero #-} -{-# SPECIALIZE toCharsNonNumbersAndZero :: SpecialStrings -> Float -> Maybe (BoundedPrim ()) #-} -{-# SPECIALIZE toCharsNonNumbersAndZero :: SpecialStrings -> Double -> Maybe (BoundedPrim ()) #-} -toCharsNonNumbersAndZero :: forall a mw. - ( CastToWord a - , MantissaBits a +{-# SPECIALIZE toCharsNonNumbersAndZero :: SpecialStrings -> Float -> Maybe Builder #-} +{-# SPECIALIZE toCharsNonNumbersAndZero :: SpecialStrings -> Double -> Maybe Builder #-} +toCharsNonNumbersAndZero :: forall a mw ew. + ( ExponentBits a , mw ~ MantissaWord a , Ord mw , Num mw + , ew ~ ExponentWord a + , Ord ew + , Num ew + , Bits ew + , Integral ew + + , ExponentBits a + , MantissaBits a + , CastToWord a + , mw ~ MantissaWord a , Bits mw + , Eq mw , Integral mw - , ExponentBits a - ) => SpecialStrings -> a -> Maybe (BoundedPrim ()) -toCharsNonNumbersAndZero SpecialStrings{..} f = boundString <$> + , ew ~ ExponentWord a + , Num ew + + ) => SpecialStrings -> a -> Maybe Builder +toCharsNonNumbersAndZero SpecialStrings{..} f = flip BP.primBounded () . boundString <$> if w .&. expoMantissaBits == 0 then Just if w == signBit then negativeZero else positiveZero else if w .&. expoMask == expoMask @@ -943,6 +956,7 @@ breakdown :: forall a mw ew. , mw ~ MantissaWord a , Bits mw , Integral mw + , ew ~ ExponentWord a , Num ew ) => a -> (Bool, mw, ew) breakdown f = (sign, mantissa, expo)