Skip to content

Commit 6b212c0

Browse files
johnnychen94timholy
authored andcommitted
enhance and export floattype (#122)
1 parent 17c4099 commit 6b212c0

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

src/FixedPointNumbers.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export
2323
FixedPoint,
2424
Fixed,
2525
Normed,
26+
floattype,
2627
# "special" typealiases
2728
# Q and U typealiases are exported in separate source files
2829
# Functions
@@ -74,9 +75,38 @@ widen1(::Type{UInt128}) = UInt128
7475
widen1(x::Integer) = x % widen1(typeof(x))
7576

7677
const ShortInts = Union{Int8,UInt8,Int16,UInt16}
78+
const LongInts = Union{UInt64, UInt128, Int64, Int128, BigInt}
7779

80+
"""
81+
floattype(::Type{T})
82+
83+
Return the minimum float type that represents `T` without overflow to `Inf`.
84+
85+
# Example
86+
87+
A classic usage is to avoid overflow behavior by promoting `FixedPoint` to `AbstractFloat`
88+
89+
```julia
90+
julia> x = N0f8(1.0)
91+
1.0N0f8
92+
93+
julia> x + x # overflow
94+
0.996N0f8
95+
96+
julia> float_x = floattype(eltype(x))(x)
97+
1.0f0
98+
99+
julia> float_x + float_x
100+
2.0f0
101+
```
102+
"""
103+
floattype(::Type{T}) where {T <: Real} = T # fallback
104+
floattype(::Type{T}) where {T <: Union{ShortInts, Bool}} = Float32
105+
floattype(::Type{T}) where {T <: Integer} = Float64
106+
floattype(::Type{T}) where {T <: LongInts} = BigFloat
78107
floattype(::Type{FixedPoint{T,f}}) where {T <: ShortInts,f} = Float32
79108
floattype(::Type{FixedPoint{T,f}}) where {T <: Integer,f} = Float64
109+
floattype(::Type{FixedPoint{T,f}}) where {T <: LongInts,f} = BigFloat
80110
floattype(::Type{F}) where {F <: FixedPoint} = floattype(supertype(F))
81111
floattype(x::FixedPoint) = floattype(typeof(x))
82112

test/runtests.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,7 @@ end
88
@testset "fixed" begin
99
include("fixed.jl")
1010
end
11+
12+
@testset "traits" begin
13+
include("traits.jl")
14+
end

test/traits.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
@testset "floattype" begin
2+
function _is_fixed_type(x::Symbol)
3+
try
4+
@eval $(x) isa Type && $(x) <: FixedPoint && return true
5+
catch
6+
return false
7+
end
8+
end
9+
10+
fixed_types = setdiff(filter(_is_fixed_type, names(FixedPointNumbers)), [:Fixed, :Normed, :FixedPoint])
11+
fixed_types = [@eval $(x) for x in fixed_types]
12+
13+
exact_types = vcat([UInt8, UInt16, UInt32, UInt64, UInt128, Bool,
14+
Int8, Int16, Int32, Int64, Int128],
15+
fixed_types)
16+
for T in exact_types
17+
@test typemax(T) <= maxintfloat(floattype(T))
18+
end
19+
end

0 commit comments

Comments
 (0)