From cab7382892556a6d751d30651e34f967cf9aabb1 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Mon, 12 Oct 2015 10:22:41 -0500 Subject: [PATCH 1/2] Fix reductions so they don't overflow --- src/FixedPointNumbers.jl | 5 +++++ test/ufixed.jl | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index d771c147..444dbc90 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -60,6 +60,11 @@ include("ufixed.jl") include("deprecations.jl") +# Promotions for reductions +for F in (Base.AddFun, Base.MulFun) + @eval Base.r_promote{T}(::$F, x::FixedPoint{T}) = Float64(x) +end + # TODO: rewrite this by @generated for T in tuple(Fixed16, UF...) R = rawtype(T) diff --git a/test/ufixed.jl b/test/ufixed.jl index d7b46eda..c4c272d2 100644 --- a/test/ufixed.jl +++ b/test/ufixed.jl @@ -153,3 +153,6 @@ b, ad = scaledual(0.5, ad) generic_scale!(rfloat, a, 0.5) generic_scale!(rfixed, ad, b) @test rfloat == rfixed + +a = UFixed8[0xffuf8, 0xffuf8] +@test sum(a) == 2.0 From 060ab8c598eabf1b8cd98aecf5e541de380e3306 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Mon, 12 Oct 2015 16:04:32 -0500 Subject: [PATCH 2/2] Also fix reductions along dimensions --- src/FixedPointNumbers.jl | 16 +++++++++++++--- test/fixed.jl | 13 +++++++++++++ test/ufixed.jl | 7 +++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index 444dbc90..8c19a2e2 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -4,13 +4,15 @@ module FixedPointNumbers using Compat +using Base: IdFun, AddFun, MulFun, reducedim_initarray + import Base: ==, <, <=, -, +, *, /, ~, convert, promote_rule, show, showcompact, isinteger, abs, decompose, isnan, isinf, isfinite, zero, one, typemin, typemax, realmin, realmax, eps, sizeof, reinterpret, trunc, round, floor, ceil, bswap, div, fld, rem, mod, mod1, rem1, fld1, min, max, - start, next, done + start, next, done, r_promote, reducedim_init # T => BaseType # f => Number of Bytes reserved for fractional part abstract FixedPoint{T <: Integer, f} <: Real @@ -61,10 +63,18 @@ include("deprecations.jl") # Promotions for reductions -for F in (Base.AddFun, Base.MulFun) - @eval Base.r_promote{T}(::$F, x::FixedPoint{T}) = Float64(x) +const Treduce = Float64 +for F in (AddFun, MulFun) + @eval r_promote{T}(::$F, x::FixedPoint{T}) = Treduce(x) end +reducedim_init{T<:FixedPoint}(f::IdFun, op::AddFun, + A::AbstractArray{T}, region) = + reducedim_initarray(A, region, zero(Treduce)) +reducedim_init{T<:FixedPoint}(f::IdFun, op::MulFun, + A::AbstractArray{T}, region) = + reducedim_initarray(A, region, one(Treduce)) + # TODO: rewrite this by @generated for T in tuple(Fixed16, UF...) R = rawtype(T) diff --git a/test/fixed.jl b/test/fixed.jl index 5cb4f124..2a14861b 100644 --- a/test/fixed.jl +++ b/test/fixed.jl @@ -53,3 +53,16 @@ for (TI, f) in [(Int8, 8), (Int16, 8), (Int16, 10), (Int32, 16)] println(" Testing $T") test_fixed(T, f) end + +# reductions +F8 = Fixed{Int8,8} +a = F8[0.498, 0.1] +acmp = Float64(a[1]) + Float64(a[2]) +@test sum(a) == acmp +@test sum(a, 1) == [acmp] + +F6 = Fixed{Int8,6} +a = F6[1.2, 1.4] +acmp = Float64(a[1])*Float64(a[2]) +@test prod(a) == acmp +@test prod(a, 1) == [acmp] diff --git a/test/ufixed.jl b/test/ufixed.jl index c4c272d2..09258bc7 100644 --- a/test/ufixed.jl +++ b/test/ufixed.jl @@ -154,5 +154,12 @@ generic_scale!(rfloat, a, 0.5) generic_scale!(rfixed, ad, b) @test rfloat == rfixed +# reductions a = UFixed8[0xffuf8, 0xffuf8] @test sum(a) == 2.0 +@test sum(a, 1) == [2.0] + +a = UFixed14[3.2, 2.4] +acmp = Float64(a[1])*Float64(a[2]) +@test prod(a) == acmp +@test prod(a, 1) == [acmp]