@@ -68,6 +68,7 @@ module Data.ByteString.Builder.RealFloat
68
68
, standardDefaultPrecision
69
69
, scientific
70
70
, generic
71
+ , shortest
71
72
) where
72
73
73
74
import Data.ByteString.Builder.Internal (Builder )
@@ -128,11 +129,18 @@ scientific = MkFloatFormat FScientific Nothing
128
129
generic :: FloatFormat
129
130
generic = MkFloatFormat FGeneric Nothing
130
131
132
+ -- | Standard or scientific notation depending on which uses the least number of charabers.
133
+ --
134
+ -- @since ????
135
+ shortest :: FloatFormat
136
+ shortest = MkFloatFormat FShortest Nothing
137
+
131
138
-- | ByteString float-to-string format
132
139
data FormatMode
133
140
= FScientific -- ^ scientific notation
134
141
| FStandard -- ^ standard notation with `Maybe Int` digits after the decimal
135
142
| FGeneric -- ^ dispatches to scientific or standard notation based on the exponent
143
+ | FShortest -- ^ the actual shortest length string of either standard notation or scientific notation
136
144
deriving Show
137
145
138
146
-- TODO: support precision argument for FGeneric and FScientific
@@ -163,8 +171,10 @@ data FormatMode
163
171
formatFloat :: FloatFormat -> Float -> Builder
164
172
formatFloat (MkFloatFormat fmt prec) = \ f ->
165
173
let (RF. FloatingDecimal m e) = RF. f2Intermediate f
166
- e' = R. int32ToInt e + R. decimalLength9 m in
167
- case fmt of
174
+ e' = e'' + olength
175
+ e'' = R. int32ToInt e
176
+ olength = R. decimalLength9 m
177
+ in case fmt of
168
178
FGeneric ->
169
179
case specialStr f of
170
180
Just b -> b
@@ -177,6 +187,14 @@ formatFloat (MkFloatFormat fmt prec) = \f ->
177
187
case specialStr f of
178
188
Just b -> b
179
189
Nothing -> sign f `mappend` showStandard (R. word32ToWord64 m) e' prec
190
+ FShortest ->
191
+ case specialStr f of
192
+ Just b -> b
193
+ Nothing ->
194
+ if e'' >= 0 && (olength + 2 >= e'' || olength == 1 && e'' <= 2 )
195
+ || e'' < 0 && (olength + e'' >= (- 3 ) || olength == 1 && e'' >= (- 2 ))
196
+ then sign f `mappend` showStandard (R. word32ToWord64 m) e' prec
197
+ else BP. primBounded (R. toCharsScientific (f < 0 ) m e) ()
180
198
181
199
-- TODO: support precision argument for FGeneric and FScientific
182
200
-- | Returns a rendered Double. Returns the \'shortest\' representation in
@@ -206,8 +224,10 @@ formatFloat (MkFloatFormat fmt prec) = \f ->
206
224
formatDouble :: FloatFormat -> Double -> Builder
207
225
formatDouble (MkFloatFormat fmt prec) = \ f ->
208
226
let (RD. FloatingDecimal m e) = RD. d2Intermediate f
209
- e' = R. int32ToInt e + R. decimalLength17 m in
210
- case fmt of
227
+ e' = e'' + olength
228
+ e'' = R. int32ToInt e
229
+ olength = R. decimalLength17 m
230
+ in case fmt of
211
231
FGeneric ->
212
232
case specialStr f of
213
233
Just b -> b
@@ -220,6 +240,14 @@ formatDouble (MkFloatFormat fmt prec) = \f ->
220
240
case specialStr f of
221
241
Just b -> b
222
242
Nothing -> sign f `mappend` showStandard m e' prec
243
+ FShortest ->
244
+ case specialStr f of
245
+ Just b -> b
246
+ Nothing ->
247
+ if e'' >= 0 && (olength + 2 >= e'' || olength == 1 && e'' <= 2 )
248
+ || e'' < 0 && (olength + e'' >= (- 3 ) || olength == 1 && e'' >= (- 2 ))
249
+ then sign f `mappend` showStandard m e' prec
250
+ else BP. primBounded (R. toCharsScientific (f < 0 ) m e) ()
223
251
224
252
-- | Char7 encode a 'Char'.
225
253
{-# INLINE char7 #-}
0 commit comments