From 692f80736fcc95aae1cf615ed2d94d755737aadc Mon Sep 17 00:00:00 2001 From: Jacob Quinn Date: Fri, 30 Aug 2019 16:44:11 -0600 Subject: [PATCH] Fix 33115 by restoring Float16/Float32 type info in show --- base/docs/basedocs.jl | 4 +- base/essentials.jl | 6 +- base/float.jl | 6 +- base/int.jl | 4 +- base/promotion.jl | 2 +- base/ryu/Ryu.jl | 12 ++-- base/ryu/shortest.jl | 59 +++++++++++++++++-- .../integers-and-floating-point-numbers.md | 22 +++---- doc/src/manual/performance-tips.md | 10 ++-- doc/src/manual/types.md | 2 +- stdlib/LinearAlgebra/test/uniformscaling.jl | 2 +- stdlib/Random/src/normal.jl | 2 +- test/float16.jl | 8 +-- test/numbers.jl | 26 ++++---- test/show.jl | 2 +- 15 files changed, 107 insertions(+), 60 deletions(-) diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index 8d644d8398171..75f59a87b5d60 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -1082,10 +1082,10 @@ Create a `Float32` from `x`. If `x` is not exactly representable then `mode` det # Examples ```jldoctest julia> Float32(1/3, RoundDown) -0.3333333 +0.3333333f0 julia> Float32(1/3, RoundUp) -0.33333334 +0.33333334f0 ``` See [`RoundingMode`](@ref) for available rounding modes. diff --git a/base/essentials.jl b/base/essentials.jl index 4de7c5bbb6989..4f36de7baecef 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -141,7 +141,7 @@ julia> x = 1/3 0.3333333333333333 julia> convert(Float32, x) -0.33333334 +0.33333334f0 julia> convert(Rational{Int32}, x) 1//3 @@ -403,11 +403,11 @@ For example, # Examples ```jldoctest julia> reinterpret(Float32, UInt32(7)) -1.0e-44 +1.0f-44 julia> reinterpret(Float32, UInt32[1 2 3 4 5]) 1×5 reinterpret(Float32, ::Array{UInt32,2}): - 1.0e-45 3.0e-45 4.0e-45 6.0e-45 7.0e-45 + 1.0f-45 3.0f-45 4.0f-45 6.0f-45 7.0f-45 ``` """ reinterpret(::Type{T}, x) where {T} = bitcast(T, x) diff --git a/base/float.jl b/base/float.jl index 37572f1a24114..6eed717e3df4d 100644 --- a/base/float.jl +++ b/base/float.jl @@ -764,10 +764,10 @@ The highest finite value representable by the given floating-point DataType `T`. # Examples ```jldoctest julia> floatmax(Float16) -65500.0 +Float16(65500.0) julia> floatmax(Float32) -3.4028235e38 +3.4028235f38 ``` """ floatmax(x::T) where {T<:AbstractFloat} = floatmax(T) @@ -790,7 +790,7 @@ julia> eps() 2.220446049250313e-16 julia> eps(Float32) -1.1920929e-7 +1.1920929f-7 julia> 1.0 + eps() 1.0000000000000002 diff --git a/base/int.jl b/base/int.jl index c5274e40a6dc5..93901166b3921 100644 --- a/base/int.jl +++ b/base/int.jl @@ -638,10 +638,10 @@ The lowest value representable by the given (real) numeric DataType `T`. # Examples ```jldoctest julia> typemin(Float16) --Inf +-Inf16 julia> typemin(Float32) --Inf +-Inf32 ``` """ function typemin end diff --git a/base/promotion.jl b/base/promotion.jl index 7709ffb98f213..46d49f5525cc3 100644 --- a/base/promotion.jl +++ b/base/promotion.jl @@ -246,7 +246,7 @@ If no arguments can be converted, an error is raised. # Examples ```jldoctest julia> promote(Int8(1), Float16(4.5), Float32(4.1)) -(1.0, 4.5, 4.1) +(1.0f0, 4.5f0, 4.1f0) ``` """ function promote end diff --git a/base/ryu/Ryu.jl b/base/ryu/Ryu.jl index ba8f7b19542bc..5005e4ec3bb3b 100644 --- a/base/ryu/Ryu.jl +++ b/base/ryu/Ryu.jl @@ -6,8 +6,8 @@ include("fixed.jl") include("exp.jl") neededdigits(::Type{Float64}) = 309 + 17 -neededdigits(::Type{Float32}) = 39 + 9 -neededdigits(::Type{Float16}) = 9 + 5 +neededdigits(::Type{Float32}) = 39 + 9 + 2 +neededdigits(::Type{Float16}) = 9 + 5 + 9 """ Ryu.writeshortest(x, plus=false, space=false, hash=true, precision=-1, expchar=UInt8('e'), padexp=false, decchar=UInt8('.')) @@ -36,7 +36,6 @@ function writeshortest(x::T, decchar::UInt8=UInt8('.')) where {T <: Base.IEEEFloat} buf = Base.StringVector(neededdigits(T)) pos = writeshortest(buf, 1, x) - @assert pos - 1 <= length(buf) return String(resize!(buf, pos - 1)) end @@ -58,7 +57,6 @@ Various options for the output format include: function writefixed(x::T, precision) where {T <: Base.IEEEFloat} buf = Base.StringVector(precision + neededdigits(T)) pos = writefixed(buf, 1, x, false, false, false, precision) - @assert pos - 1 <= length(buf) return String(resize!(buf, pos - 1)) end @@ -81,7 +79,6 @@ Various options for the output format include: function writeexp(x::T, precision) where {T <: Base.IEEEFloat} buf = Base.StringVector(precision + neededdigits(T)) pos = writeexp(buf, 1, x, false, false, false, precision) - @assert pos - 1 <= length(buf) return String(resize!(buf, pos - 1)) end @@ -90,8 +87,9 @@ function Base.show(io::IO, x::T) where {T <: Base.IEEEFloat} x = round(x, sigdigits=6) end buf = Base.StringVector(neededdigits(T)) - pos = writeshortest(buf, 1, x) - @assert pos - 1 <= length(buf) + typed = !get(io, :compact, false) && get(io, :typeinfo, Any) != typeof(x) + pos = writeshortest(buf, 1, x, false, false, true, -1, + x isa Float32 ? UInt8('f') : UInt8('e'), false, UInt8('.'), typed) write(io, resize!(buf, pos - 1)) return end diff --git a/base/ryu/shortest.jl b/base/ryu/shortest.jl index c360074a18972..28f17d1479392 100644 --- a/base/ryu/shortest.jl +++ b/base/ryu/shortest.jl @@ -1,6 +1,6 @@ @inline function writeshortest(buf::Vector{UInt8}, pos, x::T, plus=false, space=false, hash=true, - precision=-1, expchar=UInt8('e'), padexp=false, decchar=UInt8('.')) where {T} + precision=-1, expchar=UInt8('e'), padexp=false, decchar=UInt8('.'), typed=false) where {T} @assert 0 < pos <= length(buf) neg = signbit(x) # special cases @@ -23,19 +23,39 @@ end if precision == -1 buf[pos] = UInt8('0') - return pos + 1 + pos += 1 + if typed && x isa Float32 + buf[pos] = UInt8('f') + buf[pos + 1] = UInt8('0') + pos += 2 + end + return pos end while precision > 1 buf[pos] = UInt8('0') pos += 1 precision -= 1 end + if typed && x isa Float32 + buf[pos] = UInt8('f') + buf[pos + 1] = UInt8('0') + pos += 2 + end return pos elseif isnan(x) buf[pos] = UInt8('N') buf[pos + 1] = UInt8('a') buf[pos + 2] = UInt8('N') - return pos + 3 + if typed + if x isa Float32 + buf[pos + 3] = UInt8('3') + buf[pos + 4] = UInt8('2') + elseif x isa Float16 + buf[pos + 3] = UInt8('1') + buf[pos + 4] = UInt8('6') + end + end + return pos + 3 + (typed && x isa Union{Float32, Float16} ? 2 : 0) elseif !isfinite(x) if neg buf[pos] = UInt8('-') @@ -43,7 +63,16 @@ buf[pos + neg] = UInt8('I') buf[pos + neg + 1] = UInt8('n') buf[pos + neg + 2] = UInt8('f') - return pos + neg + 3 + if typed + if x isa Float32 + buf[pos + neg + 3] = UInt8('3') + buf[pos + neg + 4] = UInt8('2') + elseif x isa Float16 + buf[pos + neg + 3] = UInt8('1') + buf[pos + neg + 4] = UInt8('6') + end + end + return pos + neg + 3 + (typed && x isa Union{Float32, Float16} ? 2 : 0) end bits = uint(x) @@ -191,6 +220,17 @@ end end + if typed && x isa Float16 + buf[pos] = UInt8('F') + buf[pos + 1] = UInt8('l') + buf[pos + 2] = UInt8('o') + buf[pos + 3] = UInt8('a') + buf[pos + 4] = UInt8('t') + buf[pos + 5] = UInt8('1') + buf[pos + 6] = UInt8('6') + buf[pos + 7] = UInt8('(') + pos += 8 + end if neg buf[pos] = UInt8('-') pos += 1 @@ -205,7 +245,7 @@ olength = decimallength(output) exp_form = true pt = nexp + olength - if -4 < pt <= (precision == -1 ? (T == Float16 ? 5 : 6) : precision) #&& !(pt >= olength && abs(mod(x + 0.05, 10^(pt - olength)) - 0.05) > 0.05) + if -4 < pt <= (precision == -1 ? (T == Float16 ? 5 : 6) : precision) exp_form = false if pt <= 0 buf[pos] = UInt8('0') @@ -311,6 +351,11 @@ precision -= 1 end end + if typed && x isa Float32 + buf[pos] = UInt8('f') + buf[pos + 1] = UInt8('0') + pos += 2 + end else if olength > 1 || hash buf[pos] = decchar @@ -356,6 +401,10 @@ pos += 1 end end + if typed && x isa Float16 + buf[pos] = UInt8(')') + pos += 1 + end return pos end diff --git a/doc/src/manual/integers-and-floating-point-numbers.md b/doc/src/manual/integers-and-floating-point-numbers.md index b26eb64d37bd2..919714ea3de88 100644 --- a/doc/src/manual/integers-and-floating-point-numbers.md +++ b/doc/src/manual/integers-and-floating-point-numbers.md @@ -280,20 +280,20 @@ entered by writing an `f` in place of `e`: ```jldoctest julia> 0.5f0 -0.5 +0.5f0 julia> typeof(ans) Float32 julia> 2.5f-4 -0.00025 +0.00025f0 ``` Values can be converted to [`Float32`](@ref) easily: ```jldoctest julia> Float32(-1.5) --1.5 +-1.5f0 julia> typeof(ans) Float32 @@ -324,7 +324,7 @@ julia> sizeof(Float16(4.)) 2 julia> 2*Float16(4.) -8.0 +Float16(8.0) ``` The underscore `_` can be used as digit separator: @@ -408,10 +408,10 @@ The [`typemin`](@ref) and [`typemax`](@ref) functions also apply to floating-poi ```jldoctest julia> (typemin(Float16),typemax(Float16)) -(-Inf, Inf) +(-Inf16, Inf16) julia> (typemin(Float32),typemax(Float32)) -(-Inf, Inf) +(-Inf32, Inf32) julia> (typemin(Float64),typemax(Float64)) (-Inf, Inf) @@ -428,7 +428,7 @@ floating-point value: ```jldoctest julia> eps(Float32) -1.1920929e-7 +1.1920929f-7 julia> eps(Float64) 2.220446049250313e-16 @@ -468,13 +468,13 @@ the next largest or smallest representable floating-point number to the argument ```jldoctest julia> x = 1.25f0 -1.25 +1.25f0 julia> nextfloat(x) -1.2500001 +1.2500001f0 julia> prevfloat(x) -1.2499999 +1.2499999f0 julia> bitstring(prevfloat(x)) "00111111100111111111111111111111" @@ -706,7 +706,7 @@ Examples: ```jldoctest julia> zero(Float32) -0.0 +0.0f0 julia> zero(1.0) 0.0 diff --git a/doc/src/manual/performance-tips.md b/doc/src/manual/performance-tips.md index 4fa690e4bff2a..07c7ad0422d1d 100644 --- a/doc/src/manual/performance-tips.md +++ b/doc/src/manual/performance-tips.md @@ -275,7 +275,7 @@ julia> typeof(t.a) Float64 julia> t.a = 4.5f0 -4.5 +4.5f0 julia> typeof(t.a) Float32 @@ -285,7 +285,7 @@ In contrast, once `m` is constructed, the type of `m.a` cannot change: ```jldoctest myambig2 julia> m.a = 4.5f0 -4.5 +4.5f0 julia> typeof(m.a) Float64 @@ -306,7 +306,7 @@ julia> typeof(m.a) Float64 julia> m.a = 4.5f0 -4.5 +4.5f0 julia> typeof(m.a) Float32 @@ -1339,10 +1339,10 @@ such as `x-y == 0` implies `x == y`: julia> x = 3f-38; y = 2f-38; julia> set_zero_subnormals(true); (x - y, x == y) -(0.0, false) +(0.0f0, false) julia> set_zero_subnormals(false); (x - y, x == y) -(1.0000001e-38, false) +(1.0000001f-38, false) ``` In some applications, an alternative to zeroing subnormal numbers is to inject a tiny bit of noise. diff --git a/doc/src/manual/types.md b/doc/src/manual/types.md index 00b455afb8baf..5e2b20903c78a 100644 --- a/doc/src/manual/types.md +++ b/doc/src/manual/types.md @@ -929,7 +929,7 @@ or a type that specifies only field names: ```jldoctest julia> NamedTuple{(:a, :b),Tuple{Float32, String}}((1,"")) -(a = 1.0, b = "") +(a = 1.0f0, b = "") julia> NamedTuple{(:a, :b)}((1,"")) (a = 1, b = "") diff --git a/stdlib/LinearAlgebra/test/uniformscaling.jl b/stdlib/LinearAlgebra/test/uniformscaling.jl index 21a8cf0bb542c..d104875e65bc7 100644 --- a/stdlib/LinearAlgebra/test/uniformscaling.jl +++ b/stdlib/LinearAlgebra/test/uniformscaling.jl @@ -77,7 +77,7 @@ end @test sprint(show,MIME"text/plain"(),UniformScaling(one(ComplexF64))) == "LinearAlgebra.UniformScaling{Complex{Float64}}\n(1.0 + 0.0im)*I" @test sprint(show,MIME"text/plain"(),UniformScaling(one(Float32))) == "LinearAlgebra.UniformScaling{Float32}\n1.0*I" @test sprint(show,UniformScaling(one(ComplexF64))) == "LinearAlgebra.UniformScaling{Complex{Float64}}(1.0 + 0.0im)" -@test sprint(show,UniformScaling(one(Float32))) == "LinearAlgebra.UniformScaling{Float32}(1.0)" +@test sprint(show,UniformScaling(one(Float32))) == "LinearAlgebra.UniformScaling{Float32}(1.0f0)" let λ = complex(randn(),randn()) diff --git a/stdlib/Random/src/normal.jl b/stdlib/Random/src/normal.jl index 8d8e6352564c2..63fb33df642a3 100644 --- a/stdlib/Random/src/normal.jl +++ b/stdlib/Random/src/normal.jl @@ -86,7 +86,7 @@ The `Base` module currently provides an implementation for the types julia> rng = MersenneTwister(1234); julia> randexp(rng, Float32) -2.4835055 +2.4835055f0 julia> randexp(rng, 3, 3) 3×3 Array{Float64,2}: diff --git a/test/float16.jl b/test/float16.jl index cb10a65cd3db2..1b6ad86fc1870 100644 --- a/test/float16.jl +++ b/test/float16.jl @@ -107,7 +107,7 @@ end @test !isnan(Float16(2.6)) @test NaN16 != NaN16 @test isequal(NaN16, NaN16) - @test repr(NaN16) == "NaN" + @test repr(NaN16) == "NaN16" @test sprint(show, NaN16, context=:compact => true) == "NaN" @test isinf(Inf16) @@ -119,7 +119,7 @@ end @test Inf16 != -Inf16 @test -Inf16 < Inf16 @test isequal(Inf16, Inf16) - @test repr(Inf16) == "Inf" + @test repr(Inf16) == "Inf16" @test sprint(show, Inf16, context=:compact => true) == "Inf" @test isnan(reinterpret(Float16,0x7c01)) @@ -129,7 +129,7 @@ end @test prevfloat(-Inf16) === -Inf16 end -@test repr(Float16(44099)) == "44100.0" +@test repr(Float16(44099)) == "Float16(44100.0)" @testset "signed zeros" begin for z1 in (Float16(0.0), Float16(-0.0)), z2 in (Float16(0.0), Float16(-0.0)) @@ -159,7 +159,7 @@ end end # issue #5948 -@test string(reinterpret(Float16, 0x7bff)) == "65500.0" +@test string(reinterpret(Float16, 0x7bff)) == "Float16(65500.0)" # #9939 (and #9897) @test rationalize(Float16(0.1)) == 1//10 diff --git a/test/numbers.jl b/test/numbers.jl index 7f09038d95ee3..3b9ef75480a34 100644 --- a/test/numbers.jl +++ b/test/numbers.jl @@ -424,19 +424,19 @@ end @test sprint(show, -666665.951, context=:compact => true) == "-666666.0" @test sprint(show, -66.66666, context=:compact => true) == "-66.6667" - @test repr(1.0f0) == "1.0" - @test repr(-1.0f0) == "-1.0" - @test repr(0.0f0) == "0.0" - @test repr(-0.0f0) == "-0.0" - @test repr(0.1f0) == "0.1" - @test repr(0.2f0) == "0.2" - @test repr(0.3f0) == "0.3" - @test repr(0.1f0+0.2f0) == "0.3" - @test repr(Inf32) == "Inf" - @test repr(-Inf32) == "-Inf" - @test repr(NaN32) == "NaN" - @test repr(-NaN32) == "NaN" - @test repr(Float32(pi)) == "3.1415927" + @test repr(1.0f0) == "1.0f0" + @test repr(-1.0f0) == "-1.0f0" + @test repr(0.0f0) == "0.0f0" + @test repr(-0.0f0) == "-0.0f0" + @test repr(0.1f0) == "0.1f0" + @test repr(0.2f0) == "0.2f0" + @test repr(0.3f0) == "0.3f0" + @test repr(0.1f0+0.2f0) == "0.3f0" + @test repr(Inf32) == "Inf32" + @test repr(-Inf32) == "-Inf32" + @test repr(NaN32) == "NaN32" + @test repr(-NaN32) == "NaN32" + @test repr(Float32(pi)) == "3.1415927f0" end @testset "signs" begin @test sign(1) == 1 diff --git a/test/show.jl b/test/show.jl index 71f3785c8e76f..9dd55b81e236e 100644 --- a/test/show.jl +++ b/test/show.jl @@ -1246,7 +1246,7 @@ end @test showstr(Set([[Int16(1)]])) == "Set(Array{Int16,1}[[1]])" @test showstr([Float16(1)]) == "Float16[1.0]" @test showstr([[Float16(1)]]) == "Array{Float16,1}[[1.0]]" - @test replstr(Real[Float16(1)]) == "1-element Array{Real,1}:\n 1.0" + @test replstr(Real[Float16(1)]) == "1-element Array{Real,1}:\n Float16(1.0)" @test replstr(Array{Real}[Real[1]]) == "1-element Array{Array{Real,N} where N,1}:\n [1]" # printing tuples (Issue #25042) @test replstr(fill((Int64(1), zeros(Float16, 3)), 1)) ==