Repository: JuliaLang/julia
File: base/ryu/Ryu.jl (Julia)

Code before:

using .Base.Libc
import .Base: significand_bits, significand_mask, exponent_bits, exponent_mask, exponent_bias, exponent_max, uinttype

include("utils.jl")
include("shortest.jl")
include("fixed.jl")
include("exp.jl")

"""
    Ryu.neededdigits(T)

Number of digits necessary to represent type `T` in fixed-precision decimal.
"""
neededdigits(::Type{Float64}) = 309 + 17
neededdigits(::Type{Float32}) = 39 + 9 + 2
neededdigits(::Type{Float16}) = 9 + 5 + 9

"""
    Ryu.neededfloatdigits(T)

Number of digits necessary to represent type `T` in shortest precision.
"""
neededfloatdigits(::Type{Float64}) = 23
neededfloatdigits(::Type{Float32}) = 15
neededfloatdigits(::Type{Float16}) = 18

"""
    Ryu.writeshortest(x, plus=false, space=false, hash=true, precision=-1, expchar=UInt8('e'), padexp=false, decchar=UInt8('.'), typed=false, compact=false)
    Ryu.writeshortest(buf::AbstractVector{UInt8}, pos::Int, x, args...)

Convert a float value `x` into its "shortest" decimal string, which can be parsed back to the same value.
This function allows achieving the `%g` printf format.
Note the 2nd method allows passing in a byte buffer and position directly; callers must ensure the buffer has sufficient room to hold the entire decimal string.

Various options for the output format include:
  * `plus`: for positive `x`, prefix decimal string with a `'+'` character
  * `space`: for positive `x`, prefix decimal string with a `' '` character; overridden if `plus=true`
  * `hash`: whether the decimal point should be written, even if no additional digits are needed for precision
  * `precision`: minimum number of digits to be included in the decimal string; extra `'0'` characters will be added for padding if necessary
  * `expchar`: character to use exponent component in scientific notation
  * `padexp`: whether two digits should always be written, even for single-digit exponents (e.g. `e+1` becomes `e+01`)
  * `decchar`: decimal point character to be used
  * `typed`: whether additional type information should be printed for `Float16` / `Float32`
  * `compact`: output will be limited to 6 significant digits
"""
function writeshortest(x::T,
        plus::Bool=false,
        space::Bool=false,
        hash::Bool=true,
        precision::Integer=-1,

Review comment (suggestion):
5 + decimal point + sign bit + "e" + second sign bit + max exponent (2) = 11
```
julia> extrema(i->length(string(reinterpret(Float16, i))), typemin(UInt16):typemax(UInt16))
(3, 11)
```

(so maximum = 20 with typed=true)

Code after:

using .Base.Libc
import .Base: significand_bits, significand_mask, exponent_bits, exponent_mask, exponent_bias, exponent_max, uinttype

include("utils.jl")
include("shortest.jl")
include("fixed.jl")
include("exp.jl")

"""
    Ryu.neededdigits(T)

Number of digits necessary to represent type `T` in fixed-precision decimal.
"""
neededdigits(::Type{Float64}) = 309 + 17
neededdigits(::Type{Float32}) = 39 + 9 + 2
neededdigits(::Type{Float16}) = 9 + 5 + 9

"""
    Ryu.neededfloatdigits(T)

Number of digits necessary to represent type `T` in shortest precision.
"""
neededfloatdigits(::Type{Float64}) = 24
neededfloatdigits(::Type{Float32}) = 17
neededfloatdigits(::Type{Float16}) = 20

"""
    Ryu.writeshortest(x, plus=false, space=false, hash=true, precision=-1, expchar=UInt8('e'), padexp=false, decchar=UInt8('.'), typed=false, compact=false)
    Ryu.writeshortest(buf::AbstractVector{UInt8}, pos::Int, x, args...)

Convert a float value `x` into its "shortest" decimal string, which can be parsed back to the same value.
This function allows achieving the `%g` printf format.
Note the 2nd method allows passing in a byte buffer and position directly; callers must ensure the buffer has sufficient room to hold the entire decimal string.

Various options for the output format include:
  * `plus`: for positive `x`, prefix decimal string with a `'+'` character
  * `space`: for positive `x`, prefix decimal string with a `' '` character; overridden if `plus=true`
  * `hash`: whether the decimal point should be written, even if no additional digits are needed for precision
  * `precision`: minimum number of digits to be included in the decimal string; extra `'0'` characters will be added for padding if necessary
  * `expchar`: character to use exponent component in scientific notation
  * `padexp`: whether two digits should always be written, even for single-digit exponents (e.g. `e+1` becomes `e+01`)
  * `decchar`: decimal point character to be used
  * `typed`: whether additional type information should be printed for `Float16` / `Float32`
  * `compact`: output will be limited to 6 significant digits
"""
function writeshortest(x::T,
        plus::Bool=false,
        space::Bool=false,
        hash::Bool=true,
        precision::Integer=-1,