Skip to content

Commit

Permalink
added shortest format mode to RealFloat that prints the shortest poss…
Browse files Browse the repository at this point in the history
…ible string
  • Loading branch information
BebeSparkelSparkel committed Dec 28, 2023
1 parent 7e11412 commit 3249d0c
Showing 1 changed file with 32 additions and 4 deletions.
36 changes: 32 additions & 4 deletions Data/ByteString/Builder/RealFloat.hs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ module Data.ByteString.Builder.RealFloat
, standardDefaultPrecision
, scientific
, generic
, shortest
) where

import Data.ByteString.Builder.Internal (Builder)
Expand Down Expand Up @@ -128,11 +129,18 @@ scientific = MkFloatFormat FScientific Nothing
generic :: FloatFormat
generic = MkFloatFormat FGeneric Nothing

-- | Standard or scientific notation depending on which uses the least number of charabers.
--
-- @since ????
shortest :: FloatFormat
shortest = MkFloatFormat FShortest Nothing

-- | ByteString float-to-string format
data FormatMode
= FScientific -- ^ scientific notation
| FStandard -- ^ standard notation with `Maybe Int` digits after the decimal
| FGeneric -- ^ dispatches to scientific or standard notation based on the exponent
| FShortest -- ^ the actual shortest length string of either standard notation or scientific notation
deriving Show

-- TODO: support precision argument for FGeneric and FScientific
Expand Down Expand Up @@ -163,8 +171,10 @@ data FormatMode
formatFloat :: FloatFormat -> Float -> Builder
formatFloat (MkFloatFormat fmt prec) = \f ->
let (RF.FloatingDecimal m e) = RF.f2Intermediate f
e' = R.int32ToInt e + R.decimalLength9 m in
case fmt of
e' = e'' + olength
e'' = R.int32ToInt e
olength = R.decimalLength9 m
in case fmt of
FGeneric ->
case specialStr f of
Just b -> b
Expand All @@ -177,6 +187,14 @@ formatFloat (MkFloatFormat fmt prec) = \f ->
case specialStr f of
Just b -> b
Nothing -> sign f `mappend` showStandard (R.word32ToWord64 m) e' prec
FShortest ->
case specialStr f of
Just b -> b
Nothing ->
if e'' >= 0 && (olength + 2 >= e'' || olength == 1 && e'' <= 2)
|| e'' < 0 && (olength + e'' >= (-3) || olength == 1 && e'' >= (-2))
then sign f `mappend` showStandard (R.word32ToWord64 m) e' prec
else BP.primBounded (R.toCharsScientific (f < 0) m e) ()

-- TODO: support precision argument for FGeneric and FScientific
-- | Returns a rendered Double. Returns the \'shortest\' representation in
Expand Down Expand Up @@ -206,8 +224,10 @@ formatFloat (MkFloatFormat fmt prec) = \f ->
formatDouble :: FloatFormat -> Double -> Builder
formatDouble (MkFloatFormat fmt prec) = \f ->
let (RD.FloatingDecimal m e) = RD.d2Intermediate f
e' = R.int32ToInt e + R.decimalLength17 m in
case fmt of
e' = e'' + olength
e'' = R.int32ToInt e
olength = R.decimalLength17 m
in case fmt of
FGeneric ->
case specialStr f of
Just b -> b
Expand All @@ -220,6 +240,14 @@ formatDouble (MkFloatFormat fmt prec) = \f ->
case specialStr f of
Just b -> b
Nothing -> sign f `mappend` showStandard m e' prec
FShortest ->
case specialStr f of
Just b -> b
Nothing ->
if e'' >= 0 && (olength + 2 >= e'' || olength == 1 && e'' <= 2)
|| e'' < 0 && (olength + e'' >= (-3) || olength == 1 && e'' >= (-2))
then sign f `mappend` showStandard m e' prec
else BP.primBounded (R.toCharsScientific (f < 0) m e) ()

-- | Char7 encode a 'Char'.
{-# INLINE char7 #-}
Expand Down

0 comments on commit 3249d0c

Please sign in to comment.