Skip to content

Commit f622800

Browse files
authored
Change scaledual to match original intent. Fixes #130. (#132)
1 parent da39318 commit f622800

File tree

2 files changed

+34
-29
lines changed

2 files changed

+34
-29
lines changed

src/FixedPointNumbers.jl

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,21 @@ for f in (:rem, :mod, :mod1, :min, :max)
188188
end
189189
end
190190

191-
# When multiplying by a float, reduce two multiplies to one.
192-
# Particularly useful for arrays.
193-
scaledual(Tdual::Type, x) = oneunit(Tdual), x
194-
scaledual(b::Tdual, x) where {Tdual <: Number} = b, x
195-
scaledual(Tdual::Type, x::Union{T,AbstractArray{T}}) where {T <: FixedPoint} =
196-
convert(Tdual, 1/oneunit(T)), reinterpret(rawtype(T), x)
197-
scaledual(b::Tdual, x::Union{T,AbstractArray{T}}) where {Tdual <: Number,T <: FixedPoint} =
198-
convert(Tdual, b/oneunit(T)), reinterpret(rawtype(T), x)
191+
"""
192+
sd, ad = scaledual(s::Number, a)
193+
194+
Return `sd` and `ad` such that `sd * ad == s * a`.
195+
When `a` is an array of FixedPoint numbers, `sd*ad` might be faster to compute than `s*a`.
196+
"""
197+
scaledual(b::Number, x::Union{Number,AbstractArray{<:Number}}) = b, x
198+
scaledual(b::Number, x::FixedPoint) = b/rawone(x), reinterpret(x)
199+
scaledual(b::Number, x::AbstractArray{T}) where T <: FixedPoint =
200+
b/rawone(T), reinterpret(rawtype(T), x)
201+
202+
scaledual(::Type{Tdual}, x::Union{Number,AbstractArray{<:Number}}) where Tdual = oneunit(Tdual), x
203+
scaledual(::Type{Tdual}, x::FixedPoint) where Tdual = convert(Tdual, 1/rawone(x)), reinterpret(x)
204+
scaledual(::Type{Tdual}, x::AbstractArray{T}) where {Tdual, T <: FixedPoint} =
205+
convert(Tdual, 1/rawone(T)), reinterpret(rawtype(T), x)
199206

200207
@noinline function throw_converterror(::Type{T}, x) where {T <: FixedPoint}
201208
n = 2^(8*sizeof(T))

test/normed.jl

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -274,32 +274,30 @@ end
274274
@test eval(Meta.parse(str)) == x
275275
end
276276

277-
# scaledual
278-
function generic_scale!(C::AbstractArray, X::AbstractArray, s::Number)
279-
length(C) == length(X) || error("C must be the same length as X")
280-
for i = 1:length(X)
281-
@inbounds C[i] = X[i]*s
282-
end
283-
C
284-
end
285-
286277
@testset "scaledual" begin
287278
a = rand(UInt8, 10)
288-
rfloat = similar(a, Float32)
289-
rfixed = similar(rfloat)
290279
af8 = reinterpret(N0f8, a)
291-
292280
b = 0.5
281+
293282
bd, eld = scaledual(b, af8[1])
294-
@assert b*a[1] == bd*eld
295-
296-
b, ad = scaledual(0.5, a)
297-
@test b == 0.5
298-
@test ad == a
299-
b, ad = scaledual(0.5, ad)
300-
generic_scale!(rfloat, a, 0.5)
301-
generic_scale!(rfixed, ad, b)
302-
@test rfloat == rfixed
283+
@test b*af8[1] == bd*eld
284+
bd, ad = scaledual(b, af8)
285+
@test b*af8 == bd*ad
286+
287+
bd, eld = scaledual(b, a[1])
288+
@test b*a[1] == bd*eld
289+
bd, ad = scaledual(b, a)
290+
@test b*a == bd*ad
291+
292+
bd, eld = scaledual(Float64, af8[1])
293+
@test 1.0*af8[1] == bd*eld
294+
bd, ad = scaledual(Float64, af8)
295+
@test 1.0*af8 == bd*ad
296+
297+
bd, eld = scaledual(Float64, a[1])
298+
@test 1.0*a[1] == bd*eld
299+
bd, ad = scaledual(Float64, a)
300+
@test 1.0*a == bd*ad
303301
end
304302

305303
@testset "reductions" begin

0 commit comments

Comments
 (0)