Formatting.jl
Formatting.jl copied to clipboard
Formatting fails for `typemin(T<:Integer)`
Consider
f = FormatExpr("{1:+d}")
for T in (Int8,Int16,Int32,Int64)
@test format(f, typemin(T)) == string(typemin(T)) # Crashes
@test format(f, typemax(T)) == "+"*string(typemax(T)) # Works
end
The first test (for typemin) crashes with the error
Error During Test at REPL[26]:2
Test threw exception
Expression: format(f, typemin(T)) == string(typemin(T))
InexactError: check_top_bit(UInt32, -80)
Stacktrace:
[1] throw_inexacterror(f::Symbol, #unused#::Type{UInt32}, val::Int32)
@ Core ./boot.jl:614
[2] check_top_bit
@ ./boot.jl:628 [inlined]
[3] toUInt32
@ ./boot.jl:727 [inlined]
[4] UInt32
@ ./boot.jl:768 [inlined]
[5] +
@ ./char.jl:242 [inlined]
[6] _digitchar
@ ~/.julia/packages/Formatting/BwWBf/src/fmtcore.jl:63 [inlined]
[7] _pfmt_intdigits(out::IOBuffer, ax::Int8, op::Formatting._Dec)
@ Formatting ~/.julia/packages/Formatting/BwWBf/src/fmtcore.jl:102
[8] _pfmt_int(out::IOBuffer, sch::Char, ip::String, zs::Int64, ax::Int8, op::Formatting._Dec)
@ Formatting ~/.julia/packages/Formatting/BwWBf/src/fmtcore.jl:89
[9] _pfmt_i(out::IOBuffer, fs::FormatSpec, x::Int8, op::Formatting._Dec)
@ Formatting ~/.julia/packages/Formatting/BwWBf/src/fmtcore.jl:126
[10] printfmt(io::IOBuffer, fs::FormatSpec, x::Int8)
@ Formatting ~/.julia/packages/Formatting/BwWBf/src/fmtspec.jl:182
[11] printfmt(io::IOBuffer, fe::FormatExpr, args::Int8)
@ Formatting ~/.julia/packages/Formatting/BwWBf/src/formatexpr.jl:147
[12] sprint(::Function, ::FormatExpr, ::Vararg{Any}; context::Nothing, sizehint::Int64)
@ Base ./strings/io.jl:114
[13] sprint
@ ./strings/io.jl:107 [inlined]
[14] format(fe::FormatExpr, args::Int8)
@ Formatting ~/.julia/packages/Formatting/BwWBf/src/formatexpr.jl:165
Digging a bit, it fails because we cannot compute the absolute value of typemin(i::Integer), since in two-complement binary representation, the absolute value of the minimum number is one larger than the maximum number:
julia> abs(typemin(Int8))
-128
This makes the following logic break: https://github.com/JuliaIO/Formatting.jl/blob/e4c9f60020e965a72abae049ddac7e02bf986067/src/fmtcore.jl#L107-L139
Note that this is not broken if you use Format instead of Formatting