Skip to content

Commit 1b84e72

Browse files
committed
RoundNearest argument for rem
1 parent 7e63e6a commit 1b84e72

File tree

5 files changed

+47
-6
lines changed

5 files changed

+47
-6
lines changed

base/exports.jl

+1
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ export
407407
reinterpret,
408408
rem,
409409
rem1,
410+
rem2pi,
410411
round,
411412
sec,
412413
secd,

base/linalg/diagonal.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ det(D::Diagonal) = prod(D.diag)
9090
logdet{T<:Real}(D::Diagonal{T}) = sum(log(D.diag))
9191
function logdet{T<:Complex}(D::Diagonal{T}) #Make sure branch cut is correct
9292
x = sum(log(D.diag))
93-
-pi<imag(x)<pi ? x : real(x)+(mod2pi(imag(x)+pi)-pi)*im
93+
complex(real(x),rem2pi(imag(x),RoundNearest))
9494
end
9595
# identity matrices via eye(Diagonal{type},n)
9696
eye{T}(::Type{Diagonal{T}}, n::Int) = Diagonal(ones(T,n))

base/linalg/lu.jl

+1-3
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,7 @@ function logdet{T<:Complex,S}(A::LU{T,S})
175175
if isodd(sum(A.ipiv .!= 1:n))
176176
s = Complex(real(s), imag(s)+π)
177177
end
178-
r, a = reim(s)
179-
a = π-mod2pi-a) #Take principal branch with argument (-pi,pi]
180-
complex(r,a)
178+
complex(real(s),rem2pi(imag(s),RoundNearest))
181179
end
182180

183181
inv!{T<:BlasFloat,S<:StridedMatrix}(A::LU{T,S}) = @assertnonsingular LAPACK.getri!(A.factors, A.ipiv) A.info

base/math.jl

+37-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export sin, cos, tan, sinh, cosh, tanh, asin, acos, atan,
1111
cbrt, sqrt, erf, erfc, erfcx, erfi, dawson,
1212
significand,
1313
lgamma, hypot, gamma, lfact, max, min, minmax, ldexp, frexp,
14-
clamp, modf, ^, mod2pi,
14+
clamp, modf, ^, mod2pi, rem2pi,
1515
airy, airyai, airyprime, airyaiprime, airybi, airybiprime, airyx,
1616
besselj0, besselj1, besselj, besseljx,
1717
bessely0, bessely1, bessely, besselyx,
@@ -22,7 +22,7 @@ export sin, cos, tan, sinh, cosh, tanh, asin, acos, atan,
2222

2323
import Base: log, exp, sin, cos, tan, sinh, cosh, tanh, asin,
2424
acos, atan, asinh, acosh, atanh, sqrt, log2, log10,
25-
max, min, minmax, ^, exp2,
25+
max, min, minmax, ^, exp2, rem,
2626
exp10, expm1, log1p,
2727
sign_mask, exponent_mask, exponent_one, exponent_half,
2828
significand_mask, significand_bits, exponent_bits, exponent_bias
@@ -247,6 +247,12 @@ function frexp{T<:FloatingPoint}(A::Array{T})
247247
return (f, e)
248248
end
249249

250+
251+
rem(x::Float64, y::Float64, ::RoundingMode{:Nearest}) =
252+
ccall((:remainder, libm),Float64,(Float64,Float64),x,y)
253+
rem(x::Float32, y::Float32, ::RoundingMode{:Nearest}) =
254+
ccall((:remainderf, libm),Float32,(Float32,Float32),x,y)
255+
250256
modf(x) = rem(x,one(x)), trunc(x)
251257

252258
const _modff_temp = Float32[0]
@@ -324,6 +330,35 @@ const pi3o2_l = 1.8369701987210297e-16 # convert(Float64, pi * BigFloat(3/2) -
324330
const pi4o2_h = 6.283185307179586 # convert(Float64, pi * BigFloat(2))
325331
const pi4o2_l = 2.4492935982947064e-16 # convert(Float64, pi * BigFloat(2) - pi4o2_h)
326332

333+
function rem2pi(x::Float64, ::RoundingMode{:Nearest})
334+
abs(x) < pi && return x
335+
336+
(n,y) = ieee754_rem_pio2(x)
337+
338+
if iseven(n)
339+
if n&2 == 2 # add pi
340+
return add22condh(y[1],y[2],pi2o2_h,pi2o2_l)
341+
else # add 0
342+
return y[1]
343+
end
344+
else
345+
if n&2 == 2 # subtract pi/2
346+
return add22condh(y[1],y[2],-pi1o2_h,-pi1o2_l)
347+
else # add pi/2
348+
return add22condh(y[1],y[2],pi1o2_h,pi1o2_l)
349+
end
350+
end
351+
end
352+
353+
rem2pi(x::Float32, ::RoundingMode{:Nearest}) = Float32(rem2pi(Float64(x),RoundNearest))
354+
rem2pi(x::Int32, ::RoundingMode{:Nearest}) = rem2pi(Float64(x),RoundNearest)
355+
function rem2pi(x::Int64, ::RoundingMode{:Nearest})
356+
fx = Float64(x)
357+
fx == x || throw(ArgumentError("Int64 argument to rem2pi is too large: $x"))
358+
rem2pi(fx,RoundNearest)
359+
end
360+
361+
327362
function mod2pi(x::Float64) # or modtau(x)
328363
# with r = mod2pi(x)
329364
# a) 0 <= r < 2π (note: boundary open or closed - a bit fuzzy, due to rem_pio2 implementation)

base/mpfr.jl

+7
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,13 @@ function rem(x::BigFloat, y::BigFloat)
541541
return z
542542
end
543543

544+
function rem(x::BigFloat, y::BigFloat, ::RoundingMode{:Nearest})
545+
z = BigFloat()
546+
ccall((:mpfr_remainder, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end])
547+
return z
548+
end
549+
550+
544551
function sum(arr::AbstractArray{BigFloat})
545552
z = BigFloat(0)
546553
for i in arr

0 commit comments

Comments
 (0)