Skip to content

Switch Requires.jl to weakdep #88

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Manifest.toml
11 changes: 8 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
name = "Quadmath"
uuid = "be4d8f0f-7fa4-5f49-b795-2f01399ab2dd"
version = "0.5.13"
version = "0.5.14"

[deps]
Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"

[weakdeps]
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"

[extensions]
QuadmathSpecialFunctionsExt = ["SpecialFunctions"]

[compat]
Aqua = "0.6"
Compat = "4.4"
Printf = "<0.0.1, 1"
Random = "<0.0.1, 1"
Requires = "1.0"
SpecialFunctions = "2.0"
Test = "<0.0.1, 1"
julia = "1.6"
Expand Down
37 changes: 37 additions & 0 deletions ext/QuadmathSpecialFunctionsExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module QuadmathSpecialFunctionsExt

using Quadmath: libquadmath, Float128, Cfloat128, @quad_ccall
import SpecialFunctions
import SpecialFunctions: erf, erfc, besselj0, besselj1, bessely0, bessely1,
besselj, bessely, gamma, logabsgamma

erf(x::Float128) =
Float128(@quad_ccall(libquadmath.erfq(x::Cfloat128)::Cfloat128))
erfc(x::Float128) =
Float128(@quad_ccall(libquadmath.erfcq(x::Cfloat128)::Cfloat128))

besselj0(x::Float128) =
Float128(@quad_ccall(libquadmath.j0q(x::Cfloat128)::Cfloat128))
besselj1(x::Float128) =
Float128(@quad_ccall(libquadmath.j1q(x::Cfloat128)::Cfloat128))

bessely0(x::Float128) =
Float128(@quad_ccall(libquadmath.y0q(x::Cfloat128)::Cfloat128))
bessely1(x::Float128) =
Float128(@quad_ccall(libquadmath.y1q(x::Cfloat128)::Cfloat128))

besselj(n::Integer, x::Float128) =
Float128(@quad_ccall(libquadmath.jnq(n::Cint, x::Cfloat128)::Cfloat128))
bessely(n::Integer, x::Float128) =
Float128(@quad_ccall(libquadmath.ynq(n::Cint, x::Cfloat128)::Cfloat128))

gamma(x::Float128) =
Float128(@quad_ccall(libquadmath.tgammaq(x::Cfloat128)::Cfloat128))

function logabsgamma(x::Float128)
result = Float128(@quad_ccall(libquadmath.lgammaq(x::Cfloat128)::Cfloat128))
sign = !isfinite(result) || x >= 0 || !iszero(mod(ceil(x), 2)) ? 1 : -1
return result, sign
end

end
85 changes: 40 additions & 45 deletions src/Quadmath.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
module Quadmath
using Requires
using Compat: @assume_effects

export Float128, ComplexF128, Inf128
Expand Down Expand Up @@ -42,7 +41,7 @@ elseif Sys.iswindows()
const libquadmath = "libquadmath-0.dll"
end

macro ccall(expr)
macro quad_ccall(expr)
@assert expr isa Expr && expr.head == :(::)
ret_type = expr.args[2]

Expand Down Expand Up @@ -116,13 +115,6 @@ reinterpret(::Type{Int128}, x::Float128) =
reinterpret(::Type{Float128}, x::Int128) =
reinterpret(Float128, reinterpret(UInt128, x))

function __init__()
@require SpecialFunctions="276daf66-3868-5448-9aa4-cd146d93841b" begin
include("specfun.jl")
end
end


sign_mask(::Type{Float128}) = 0x8000_0000_0000_0000_0000_0000_0000_0000
exponent_mask(::Type{Float128}) = 0x7fff_0000_0000_0000_0000_0000_0000_0000
exponent_one(::Type{Float128}) = 0x3fff_0000_0000_0000_0000_0000_0000_0000
Expand All @@ -147,15 +139,15 @@ Float128(x::Float128) = x

# Float64
@assume_effects :foldable Float128(x::Float64) =
Float128(@ccall(quadoplib.__extenddftf2(x::Cdouble)::Cfloat128))
Float128(@quad_ccall(quadoplib.__extenddftf2(x::Cdouble)::Cfloat128))
@assume_effects :foldable Float64(x::Float128) =
@ccall(quadoplib.__trunctfdf2(x::Cfloat128)::Cdouble)
@quad_ccall(quadoplib.__trunctfdf2(x::Cfloat128)::Cdouble)

# Float32
@assume_effects :foldable Float128(x::Float32) =
Float128(@ccall(quadoplib.__extendsftf2(x::Cfloat)::Cfloat128))
Float128(@quad_ccall(quadoplib.__extendsftf2(x::Cfloat)::Cfloat128))
@assume_effects :foldable Float32(x::Float128) =
@ccall(quadoplib.__trunctfsf2(x::Cfloat128)::Cfloat)
@quad_ccall(quadoplib.__trunctfsf2(x::Cfloat128)::Cfloat)

# Float16
Float128(x::Float16) = Float128(Float32(x))
Expand All @@ -167,16 +159,16 @@ Float128(x::Base.TwicePrecision{Float64}) =

# integer -> Float128
@assume_effects :foldable Float128(x::Int32) =
Float128(@ccall(quadoplib.__floatsitf(x::Int32)::Cfloat128))
Float128(@quad_ccall(quadoplib.__floatsitf(x::Int32)::Cfloat128))

@assume_effects :foldable Float128(x::UInt32) =
Float128(@ccall(quadoplib.__floatunsitf(x::UInt32)::Cfloat128))
Float128(@quad_ccall(quadoplib.__floatunsitf(x::UInt32)::Cfloat128))

@assume_effects :foldable Float128(x::Int64) =
Float128(@ccall(quadoplib.__floatditf(x::Int64)::Cfloat128))
Float128(@quad_ccall(quadoplib.__floatditf(x::Int64)::Cfloat128))

@assume_effects :foldable Float128(x::UInt64) =
Float128(@ccall(quadoplib.__floatunditf(x::UInt64)::Cfloat128))
Float128(@quad_ccall(quadoplib.__floatunditf(x::UInt64)::Cfloat128))

Float128(x::Int16) = Float128(Int32(x))
Float128(x::Int8) = Float128(Int32(x))
Expand Down Expand Up @@ -238,37 +230,37 @@ Float128(x::Bool) = x ? Float128(1) : Float128(0)

# Comparison
@assume_effects :foldable (==)(x::Float128, y::Float128) =
@ccall(quadoplib.__eqtf2(x::Cfloat128, y::Cfloat128)::Cint) == 0
@quad_ccall(quadoplib.__eqtf2(x::Cfloat128, y::Cfloat128)::Cint) == 0
@assume_effects :foldable (<)(x::Float128, y::Float128) =
@ccall(quadoplib.__letf2(x::Cfloat128, y::Cfloat128)::Cint) == -1
@quad_ccall(quadoplib.__letf2(x::Cfloat128, y::Cfloat128)::Cint) == -1
@assume_effects :foldable (<=)(x::Float128, y::Float128) =
@ccall(quadoplib.__letf2(x::Cfloat128, y::Cfloat128)::Cint) <= 0
@quad_ccall(quadoplib.__letf2(x::Cfloat128, y::Cfloat128)::Cint) <= 0

# Arithmetic
@assume_effects :foldable (+)(x::Float128, y::Float128) =
Float128(@ccall(quadoplib.__addtf3(x::Cfloat128, y::Cfloat128)::Cfloat128))
Float128(@quad_ccall(quadoplib.__addtf3(x::Cfloat128, y::Cfloat128)::Cfloat128))
@assume_effects :foldable (-)(x::Float128, y::Float128) =
Float128(@ccall(quadoplib.__subtf3(x::Cfloat128, y::Cfloat128)::Cfloat128))
Float128(@quad_ccall(quadoplib.__subtf3(x::Cfloat128, y::Cfloat128)::Cfloat128))
@assume_effects :foldable (*)(x::Float128, y::Float128) =
Float128(@ccall(quadoplib.__multf3(x::Cfloat128, y::Cfloat128)::Cfloat128))
Float128(@quad_ccall(quadoplib.__multf3(x::Cfloat128, y::Cfloat128)::Cfloat128))
@assume_effects :foldable (/)(x::Float128, y::Float128) =
Float128(@ccall(quadoplib.__divtf3(x::Cfloat128, y::Cfloat128)::Cfloat128))
Float128(@quad_ccall(quadoplib.__divtf3(x::Cfloat128, y::Cfloat128)::Cfloat128))

@assume_effects :foldable (-)(x::Float128) =
Float128(@ccall(quadoplib.__negtf2(x::Cfloat128)::Cfloat128))
Float128(@quad_ccall(quadoplib.__negtf2(x::Cfloat128)::Cfloat128))

# Float128 -> Integer
@assume_effects :foldable unsafe_trunc(::Type{Int32}, x::Float128) =
@ccall(quadoplib.__fixtfsi(x::Cfloat128)::Int32)
@quad_ccall(quadoplib.__fixtfsi(x::Cfloat128)::Int32)

@assume_effects :foldable unsafe_trunc(::Type{Int64}, x::Float128) =
@ccall(quadoplib.__fixtfdi(x::Cfloat128)::Int64)
@quad_ccall(quadoplib.__fixtfdi(x::Cfloat128)::Int64)

@assume_effects :foldable unsafe_trunc(::Type{UInt32}, x::Float128) =
@ccall(quadoplib.__fixunstfsi(x::Cfloat128)::UInt32)
@quad_ccall(quadoplib.__fixunstfsi(x::Cfloat128)::UInt32)

@assume_effects :foldable unsafe_trunc(::Type{UInt64}, x::Float128) =
@ccall(quadoplib.__fixunstfdi(x::Cfloat128)::UInt64)
@quad_ccall(quadoplib.__fixunstfdi(x::Cfloat128)::UInt64)

function unsafe_trunc(::Type{UInt128}, x::Float128)
xu = reinterpret(UInt128,x)
Expand Down Expand Up @@ -340,19 +332,19 @@ for f in (:acos, :acosh, :asin, :asinh, :atan, :atanh, :cosh, :cos,
:sin, :sinh, :sqrt, :tan, :tanh,
:ceil, :floor, :trunc, )
@eval @assume_effects :foldable function $f(x::Float128)
Float128(@ccall(libquadmath.$(string(f,:q))(x::Cfloat128)::Cfloat128))
Float128(@quad_ccall(libquadmath.$(string(f,:q))(x::Cfloat128)::Cfloat128))
end
end

@assume_effects :foldable abs(x::Float128) = Float128(@ccall(libquadmath.fabsq(x::Cfloat128)::Cfloat128))
@assume_effects :foldable round(x::Float128) = Float128(@ccall(libquadmath.rintq(x::Cfloat128)::Cfloat128))
@assume_effects :foldable abs(x::Float128) = Float128(@quad_ccall(libquadmath.fabsq(x::Cfloat128)::Cfloat128))
@assume_effects :foldable round(x::Float128) = Float128(@quad_ccall(libquadmath.rintq(x::Cfloat128)::Cfloat128))
round(x::Float128, r::RoundingMode{:Down}) = floor(x)
round(x::Float128, r::RoundingMode{:Up}) = ceil(x)
round(x::Float128, r::RoundingMode{:ToZero}) = round(x)

## two argument
@assume_effects :foldable (^)(x::Float128, y::Float128) =
Float128(@ccall(libquadmath.powq(x::Cfloat128, y::Cfloat128)::Cfloat128))
Float128(@quad_ccall(libquadmath.powq(x::Cfloat128, y::Cfloat128)::Cfloat128))

# circumvent a failure in Base
function (^)(x::Float128, p::Integer)
Expand All @@ -363,15 +355,15 @@ function (^)(x::Float128, p::Integer)
end
end
@assume_effects :foldable copysign(x::Float128, y::Float128) =
Float128(@ccall(libquadmath.copysignq(x::Cfloat128, y::Cfloat128)::Cfloat128))
Float128(@quad_ccall(libquadmath.copysignq(x::Cfloat128, y::Cfloat128)::Cfloat128))
@assume_effects :foldable hypot(x::Float128, y::Float128) =
Float128(@ccall(libquadmath.hypotq(x::Cfloat128, y::Cfloat128)::Cfloat128))
Float128(@quad_ccall(libquadmath.hypotq(x::Cfloat128, y::Cfloat128)::Cfloat128))
@assume_effects :foldable atan(x::Float128, y::Float128) =
Float128(@ccall(libquadmath.atan2q(x::Cfloat128, y::Cfloat128)::Cfloat128))
Float128(@quad_ccall(libquadmath.atan2q(x::Cfloat128, y::Cfloat128)::Cfloat128))

Base.Integer(x::Float128) = Int(x)
@assume_effects :foldable Base.rem(x::Float128, y::Float128) =
Float128(@ccall(libquadmath.remainderq(x::Cfloat128, y::Cfloat128)::Cfloat128))
Float128(@quad_ccall(libquadmath.remainderq(x::Cfloat128, y::Cfloat128)::Cfloat128))

sincos(x::Float128) = (sin(x), cos(x))

Expand All @@ -380,12 +372,12 @@ sincos(x::Float128) = (sin(x), cos(x))
# disable fma on Windows until rounding mode issue fixed
# https://github.com/JuliaMath/Quadmath.jl/issues/31
@assume_effects :foldable fma(x::Float128, y::Float128, z::Float128) =
Float128(@ccall(libquadmath.fmaq(x::Cfloat128, y::Cfloat128, z::Cfloat128)::Cfloat128))
Float128(@quad_ccall(libquadmath.fmaq(x::Cfloat128, y::Cfloat128, z::Cfloat128)::Cfloat128))
end

@assume_effects :foldable isnan(x::Float128) = 0 != @ccall(libquadmath.isnanq(x::Cfloat128)::Cint)
@assume_effects :foldable isinf(x::Float128) = 0 != @ccall(libquadmath.isinfq(x::Cfloat128)::Cint)
@assume_effects :foldable isfinite(x::Float128) = 0 != @ccall(libquadmath.finiteq(x::Cfloat128)::Cint)
@assume_effects :foldable isnan(x::Float128) = 0 != @quad_ccall(libquadmath.isnanq(x::Cfloat128)::Cint)
@assume_effects :foldable isinf(x::Float128) = 0 != @quad_ccall(libquadmath.isinfq(x::Cfloat128)::Cint)
@assume_effects :foldable isfinite(x::Float128) = 0 != @quad_ccall(libquadmath.finiteq(x::Cfloat128)::Cint)

isinteger(x::Float128) = isfinite(x) && x === trunc(x)

Expand All @@ -410,14 +402,14 @@ typemax(::Type{Float128}) = Inf128
typemin(::Type{Float128}) = -Inf128

@assume_effects :foldable ldexp(x::Float128, n::Cint) =
Float128(@ccall(libquadmath.ldexpq(x::Cfloat128, n::Cint)::Cfloat128))
Float128(@quad_ccall(libquadmath.ldexpq(x::Cfloat128, n::Cint)::Cfloat128))
ldexp(x::Float128, n::Integer) =
ldexp(x, clamp(n, typemin(Cint), typemax(Cint)) % Cint)


@assume_effects :foldable function frexp(x::Float128)
ri = Ref{Cint}()
f = Float128(@ccall(libquadmath.frexpq(x::Cfloat128, ri::Ptr{Cint})::Cfloat128))
f = Float128(@quad_ccall(libquadmath.frexpq(x::Cfloat128, ri::Ptr{Cint})::Cfloat128))
return f, Int(ri[])
end

Expand Down Expand Up @@ -621,13 +613,13 @@ end

# TODO: need to do this better
function parse(::Type{Float128}, s::AbstractString)
Float128(@ccall(libquadmath.strtoflt128(s::Cstring, C_NULL::Ptr{Ptr{Cchar}})::Cfloat128))
Float128(@quad_ccall(libquadmath.strtoflt128(s::Cstring, C_NULL::Ptr{Ptr{Cchar}})::Cfloat128))
end

function string(x::Float128)
lng = 64
buf = Array{UInt8}(undef, lng + 1)
lng = @ccall(libquadmath.quadmath_snprintf(buf::Ptr{UInt8}, (lng+1)::Csize_t, "%.35Qe"::Ptr{UInt8}, x::(Cfloat128...))::Cint)
lng = @quad_ccall(libquadmath.quadmath_snprintf(buf::Ptr{UInt8}, (lng+1)::Csize_t, "%.35Qe"::Ptr{UInt8}, x::(Cfloat128...))::Cint)
return String(resize!(buf, lng))
end

Expand All @@ -636,4 +628,7 @@ show(io::IO, b::Float128) = print(io, string(b))

include("printf.jl")

if !isdefined(Base, :get_extension)
include("../ext/QuadmathSpecialFunctionsExt.jl")
end
end # module Quadmath
32 changes: 0 additions & 32 deletions src/specfun.jl

This file was deleted.

Loading