Copyright | (c) Lawrence Wu 2021 |
---|---|

License | BSD-style |

Maintainer | lawrencejwu@gmail.com |

Safe Haskell | Safe-Inferred |

Language | Haskell2010 |

Floating point formatting for `Bytestring.Builder`

This module primarily exposes `floatDec`

and `doubleDec`

which do the
equivalent of converting through

.`string7`

. `show`

It also exposes `formatFloat`

and `formatDouble`

with a similar API as
`formatRealFloat`

.

NB: The float-to-string conversions exposed by this module match `show`

's
output (specifically with respect to default rounding and length). In
particular, there are boundary cases where the closest and 'shortest'
string representations are not used. Mentions of 'shortest' in the docs
below are with this caveat.

For example, for fidelity, we match `show`

on the output below.

`>>>`

"1.0e23"`show (1.0e23 :: Float)`

`>>>`

"9.999999999999999e22"`show (1.0e23 :: Double)`

`>>>`

"1.0e23"`floatDec 1.0e23`

`>>>`

"9.999999999999999e22"`doubleDec 1.0e23`

Simplifying, we can build a shorter, lossless representation by just using
`"1.0e23"`

since the floating point values that are 1 ULP away are

`>>>`

"44b52d02c7e14af6"`showHex (castDoubleToWord64 1.0e23) []`

`>>>`

9.999999999999997e22`castWord64ToDouble 0x44b52d02c7e14af5`

`>>>`

9.999999999999999e22`castWord64ToDouble 0x44b52d02c7e14af6`

`>>>`

1.0000000000000001e23`castWord64ToDouble 0x44b52d02c7e14af7`

In particular, we could use the exact boundary if it is the shortest
representation and the original floating number is even. To experiment with
the shorter rounding, refer to
`acceptBounds`

. This will give us

`>>>`

"1.0e23"`floatDec 1.0e23`

`>>>`

"1.0e23"`doubleDec 1.0e23`

For more details, please refer to the Ryu paper.

*Since: bytestring-0.11.2.0*

## Synopsis

- floatDec :: Float -> Builder
- doubleDec :: Double -> Builder
- formatFloat :: FloatFormat -> Float -> Builder
- formatDouble :: FloatFormat -> Double -> Builder
- data FloatFormat
- standard :: Int -> FloatFormat
- standardDefaultPrecision :: FloatFormat
- scientific :: FloatFormat
- generic :: FloatFormat

# Documentation

floatDec :: Float -> Builder Source #

Returns a rendered Float. Matches `show`

in displaying in standard or
scientific notation

floatDec =`formatFloat`

`generic`

doubleDec :: Double -> Builder Source #

Returns a rendered Double. Matches `show`

in displaying in standard or
scientific notation

doubleDec =`formatDouble`

`generic`

# Custom formatting

formatFloat :: FloatFormat -> Float -> Builder Source #

Returns a rendered Float. Returns the 'shortest' representation in
scientific notation and takes an optional precision argument in standard
notation. Also see `floatDec`

.

With standard notation, the precision argument is used to truncate (or extend with 0s) the 'shortest' rendered Float. The 'default precision' does no such modifications and will return as many decimal places as the representation demands.

e.g

`>>>`

"0.0"`formatFloat (standard 1) 1.2345e-2`

`>>>`

"0.0123450000"`formatFloat (standard 10) 1.2345e-2`

`>>>`

"0.01234"`formatFloat standardDefaultPrecision 1.2345e-2`

`>>>`

"1.2345e1"`formatFloat scientific 12.345`

`>>>`

"12.345"`formatFloat generic 12.345`

*Since: bytestring-0.11.2.0*

formatDouble :: FloatFormat -> Double -> Builder Source #

Returns a rendered Double. Returns the 'shortest' representation in
scientific notation and takes an optional precision argument in standard
notation. Also see `doubleDec`

.

With standard notation, the precision argument is used to truncate (or extend with 0s) the 'shortest' rendered Float. The 'default precision' does no such modifications and will return as many decimal places as the representation demands.

e.g

`>>>`

"0.0"`formatDouble (standard 1) 1.2345e-2`

`>>>`

"0.0123450000"`formatDouble (standard 10) 1.2345e-2`

`>>>`

"0.01234"`formatDouble standardDefaultPrecision 1.2345e-2`

`>>>`

"1.2345e1"`formatDouble scientific 12.345`

`>>>`

"12.345"`formatDouble generic 12.345`

*Since: bytestring-0.11.2.0*

data FloatFormat Source #

Format type for use with `formatFloat`

and `formatDouble`

.

*Since: bytestring-0.11.2.0*

standard :: Int -> FloatFormat Source #

Standard notation with `n`

decimal places

*Since: bytestring-0.11.2.0*

standardDefaultPrecision :: FloatFormat Source #

Standard notation with the 'default precision' (decimal places matching `show`

)

*Since: bytestring-0.11.2.0*

scientific :: FloatFormat Source #

Scientific notation with 'default precision' (decimal places matching `show`

)

*Since: bytestring-0.11.2.0*

generic :: FloatFormat Source #

Standard or scientific notation depending on the exponent. Matches `show`

*Since: bytestring-0.11.2.0*