From 950cea6f6d6a21649a137fec6324b32934b76177 Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Thu, 12 May 2022 20:15:13 -0400 Subject: [PATCH] generic frexp --- src/math/prearith/prearith.jl | 18 +++++++++++++++--- test/prearith.jl | 18 ++++++++++++++---- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/math/prearith/prearith.jl b/src/math/prearith/prearith.jl index 52911790..207f7fbd 100644 --- a/src/math/prearith/prearith.jl +++ b/src/math/prearith/prearith.jl @@ -41,21 +41,33 @@ end flipsign(x::DoubleFloat{T}, y::U) where {T<:IEEEFloat, U<:Unsigned} = +x copysign(x::DoubleFloat{T}, y::U) where {T<:IEEEFloat, U<:Unsigned} = +x -function Base.Math.frexp(x::DoubleFloat{T}) where {T<:IEEEFloat} +""" + frexps(x::DoubleFloat) + +Applies `Base.frexp` to both `hi` and `lo` parts, and returns a tuple of tuples. +See also `DoubleFloats.ldexps` for the inverse, and `DoubleFloats.signs` similar tuple. +""" +function frexps(x::DoubleFloat{T}) where {T<:IEEEFloat} frhi, exphi = frexp(HI(x)) frlo, explo = frexp(LO(x)) return (frhi, exphi), (frlo, explo) end +function Base.Math.frexp(x::DoubleFloat{T}) where {T<:IEEEFloat} + frhi, exphi = frexp(HI(x)) + frlo, explo = frexp(LO(x)) + return DoubleFloat{T}(frhi, ldexp(frlo, explo - exphi)), exphi +end + function Base.Math.ldexp(x::DoubleFloat{T}, exponent::I) where {T<:IEEEFloat, I<:Integer} return DoubleFloat{T}(ldexp(HI(x), exponent), ldexp(LO(x), exponent)) end -function Base.Math.ldexp(dhi::Tuple{T,I}, dlo::Tuple{T,I}) where {T<:IEEEFloat, I<:Integer} +function ldexps(dhi::Tuple{T,I}, dlo::Tuple{T,I}) where {T<:IEEEFloat, I<:Integer} return DoubleFloat(ldexp(dhi[1], dhi[2]), ldexp(dlo[1], dlo[2])) end -function Base.Math.ldexp(dhilo::Tuple{Tuple{T,I}, Tuple{T,I}}) where {T<:IEEEFloat, I<:Integer} +function ldexps(dhilo::Tuple{Tuple{T,I}, Tuple{T,I}}) where {T<:IEEEFloat, I<:Integer} return ldexp(dhilo[1], dhilo[2]) end diff --git a/test/prearith.jl b/test/prearith.jl index f678d113..7cdaa76e 100644 --- a/test/prearith.jl +++ b/test/prearith.jl @@ -10,12 +10,22 @@ @test flipsign(negval, 1) == negval @test copysign(val, -1) == negval @test copysign(negval, 1) == val - + @test ldexp(frexp(val)...,) == val - # @test ldexp(significand(val), exponent(val)) == val - - @test signs(val) == (sign(HI(val)), sign(LO(val))) + fr, ex = frexp(val) + @test fr * T(2)^ex == val + + @test fr ≈ frexp(Float64(val))[1] + @test ex == frexp(Float64(val))[2] + @test isnan(frexp(T(NaN))[1]) + @test isinf(frexp(T(Inf))[1]) + @test iszero(frexp(T(0))[1]) + + @test DoubleFloats.ldexps(DoubleFloats.frexps(val)...,) == val + # @test ldexp(significand(val), exponent(val)) == val + + @test signs(val) == (sign(HI(val)), sign(LO(val))) end @testset "trunc $T" for T in (Double16, Double32, Double64)