@@ -4,11 +4,11 @@ module FixedPointNumbers
44
55using Base: reducedim_initarray
66
7- import Base: == , < , <= , - , + , * , / , ~ ,
7+ import Base: == , < , <= , - , + , * , / , ~ , isapprox,
88 convert, promote_rule, show, showcompact, isinteger, abs, decompose,
99 isnan, isinf, isfinite,
1010 zero, one, typemin, typemax, realmin, realmax, eps, sizeof, reinterpret,
11- trunc, round, floor, ceil, bswap,
11+ float, trunc, round, floor, ceil, bswap,
1212 div, fld, rem, mod, mod1, rem1, fld1, min, max, minmax,
1313 start, next, done, r_promote, reducedim_init
1414
@@ -51,10 +51,24 @@ reinterpret(x::FixedPoint) = x.i
5151== {T <: FixedPoint }(x:: T , y:: T ) = x. i == y. i
5252 < {T <: FixedPoint }(x:: T , y:: T ) = x. i < y. i
5353<= {T <: FixedPoint }(x:: T , y:: T ) = x. i <= y. i
54+ """
55+ isapprox(x::FixedPoint, y::FixedPoint; rtol=0, atol=max(eps(x), eps(y)))
56+
57+ For FixedPoint numbers, the default criterion is that `x` and `y` differ by no more than `eps`, the separation between adjacent fixed-point numbers.
58+ """
59+ function isapprox {T<:FixedPoint} (x:: T , y:: T ; rtol= 0 , atol= max (eps (x), eps (y)))
60+ maxdiff = T (atol+ rtol* max (abs (x), abs (y)))
61+ rx, ry, rd = reinterpret (x), reinterpret (y), reinterpret (maxdiff)
62+ abs (signed (widen1 (rx))- signed (widen1 (ry))) <= rd
63+ end
64+ function isapprox (x:: FixedPoint , y:: FixedPoint ; rtol= 0 , atol= max (eps (x), eps (y)))
65+ isapprox (promote (x, y)... ; rtol= rtol, atol= atol)
66+ end
5467
5568# predicates
5669isinteger {T,f} (x:: FixedPoint{T,f} ) = (x. i& (1 << f- 1 )) == 0
5770
71+ # traits
5872typemax {T<: FixedPoint} (:: Type{T} ) = T (typemax (rawtype (T)), 0 )
5973typemin {T<: FixedPoint} (:: Type{T} ) = T (typemin (rawtype (T)), 0 )
6074realmin {T<: FixedPoint} (:: Type{T} ) = typemin (T)
@@ -70,10 +84,25 @@ widen1(::Type{Int64}) = Int128
7084widen1 (:: Type{UInt64} ) = UInt128
7185widen1 (x:: Integer ) = x % widen1 (typeof (x))
7286
87+ if VERSION <= v " 0.5.0-dev+755"
88+ @generated function floattype {T,f} (:: Type{FixedPoint{T,f}} )
89+ f> 22 ? :(Float64) : :(Float32)
90+ end
91+ else
92+ @pure function floattype {T,f} (:: Type{FixedPoint{T,f}} )
93+ f> 22 ? Float64 : Float32
94+ end
95+ end
96+ floattype (x:: FixedPoint ) = floattype (supertype (typeof (x)))
97+
98+
7399include (" fixed.jl" )
74100include (" ufixed.jl" )
75101include (" deprecations.jl" )
76102
103+ eps {T<:FixedPoint} (:: Type{T} ) = T (one (rawtype (T)),0 )
104+ eps {T<:FixedPoint} (:: T ) = eps (T)
105+ sizeof {T<:FixedPoint} (:: Type{T} ) = sizeof (rawtype (T))
77106
78107# Promotions for reductions
79108const Treduce = Float64
@@ -97,6 +126,17 @@ for T in tuple(Fixed16, UF...)
97126 end
98127end
99128
129+ for f in (:div , :fld , :fld1 )
130+ @eval begin
131+ $ f {T<:FixedPoint} (x:: T , y:: T ) = $ f (reinterpret (x),reinterpret (y))
132+ end
133+ end
134+ for f in (:rem , :mod , :mod1 , :rem1 , :min , :max )
135+ @eval begin
136+ $ f {T<:FixedPoint} (x:: T , y:: T ) = T ($ f (reinterpret (x),reinterpret (y)),0 )
137+ end
138+ end
139+
100140# When multiplying by a float, reduce two multiplies to one.
101141# Particularly useful for arrays.
102142scaledual (Tdual:: Type , x) = one (Tdual), x
@@ -115,7 +155,7 @@ function show{T,f}(io::IO, x::FixedPoint{T,f})
115155 print (io, " )" )
116156end
117157const _log2_10 = 3.321928094887362
118- showcompact {T,f} (io:: IO , x:: FixedPoint{T,f} ) = show (io, round (convert (Float64, x), ceil (Int,f/ _log2_10)))
158+ showcompact {T,f} (io:: IO , x:: FixedPoint{T,f} ) = show (io, round (float ( x), ceil (Int,f/ _log2_10)))
119159
120160@noinline function throw_converterror {T<:FixedPoint} (:: Type{T} , x)
121161 n = 2 ^ (8 * sizeof (T))
0 commit comments