From c8582295f7a4c74afb563902b5470966a480f99d Mon Sep 17 00:00:00 2001 From: Jeffrey Sarnoff Date: Tue, 16 Jun 2020 05:20:49 -0400 Subject: [PATCH 1/3] `fma` using `BigFloats` on `Sys.iswindows()` --- src/Quadmath.jl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Quadmath.jl b/src/Quadmath.jl index e5d9d97..465ad88 100644 --- a/src/Quadmath.jl +++ b/src/Quadmath.jl @@ -347,10 +347,16 @@ sincos(x::Float128) = (sin(x), cos(x)) ## misc @static if !Sys.iswindows() - # disable fma on Windows until rounding mode issue fixed - # https://github.com/JuliaMath/Quadmath.jl/issues/31 fma(x::Float128, y::Float128, z::Float128) = Float128(@ccall(libquadmath.fmaq(x::Cfloat128, y::Cfloat128, z::Cfloat128)::Cfloat128)) +else # use BigFloats (https://github.com/JuliaMath/Quadmath.jl/issues/31) + function fma(x::Float128, y::Float128, z::Float128) + oldprec = precision(BigFloat) + setprecision(BigFloat, 512) # 512 > significand_bits(Float128) * 3.5 + result = Float128(fma(BigFloat(x), BigFloat(y), BigFloat(z))) + setprecision(BigFloat, oldprec) + return result + end end isnan(x::Float128) = 0 != @ccall(libquadmath.isnanq(x::Cfloat128)::Cint) From 01ae948b70bb755c100713633d8059a0c078066c Mon Sep 17 00:00:00 2001 From: Jeffrey Sarnoff Date: Tue, 16 Jun 2020 05:39:19 -0400 Subject: [PATCH 2/3] adjust BigFloat precision for Sys.windows() fma --- src/Quadmath.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Quadmath.jl b/src/Quadmath.jl index 465ad88..78c9b15 100644 --- a/src/Quadmath.jl +++ b/src/Quadmath.jl @@ -352,7 +352,7 @@ sincos(x::Float128) = (sin(x), cos(x)) else # use BigFloats (https://github.com/JuliaMath/Quadmath.jl/issues/31) function fma(x::Float128, y::Float128, z::Float128) oldprec = precision(BigFloat) - setprecision(BigFloat, 512) # 512 > significand_bits(Float128) * 3.5 + setprecision(BigFloat, 192) # 1.5 * bitsof(Float64) == 192 > significand_bits(Float128) result = Float128(fma(BigFloat(x), BigFloat(y), BigFloat(z))) setprecision(BigFloat, oldprec) return result From 6d6e1ba09a58fe647685054304ef5ef9f1f54fe5 Mon Sep 17 00:00:00 2001 From: Jeffrey Sarnoff Date: Sat, 20 Jun 2020 16:21:49 -0400 Subject: [PATCH 3/3] for fma, setprecision(BigFloat,113) After much consideration and some testing, since we are using MPFR's `fma`, it is appropriate to use 113 bits of precision. FMA implementations (even on chip) do not really evaluate as if infinite bits of precision were available. --- src/Quadmath.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Quadmath.jl b/src/Quadmath.jl index 78c9b15..155fe17 100644 --- a/src/Quadmath.jl +++ b/src/Quadmath.jl @@ -352,7 +352,7 @@ sincos(x::Float128) = (sin(x), cos(x)) else # use BigFloats (https://github.com/JuliaMath/Quadmath.jl/issues/31) function fma(x::Float128, y::Float128, z::Float128) oldprec = precision(BigFloat) - setprecision(BigFloat, 192) # 1.5 * bitsof(Float64) == 192 > significand_bits(Float128) + setprecision(BigFloat, 113) # significand_bits(Float128) + hiddenbit result = Float128(fma(BigFloat(x), BigFloat(y), BigFloat(z))) setprecision(BigFloat, oldprec) return result