Well, I do not want to add packages to my project unless really needed. I use now:
"""
wrap2pi(angle)
Limit the angle to the range -π .. π .
"""
wrap2pi(::typeof(pi)) = π
function wrap2pi(angle)
y = rem(angle, 2π)
abs(y) > π && (y -= 2π * sign(y))
return y
end
I prefer to use == instead of isapprox if it works. And here it works just fine. The code is also simple and fast, about the same performance as sin().
Beware of false expectations though. Since wrap2pi(-π) == -π holds, then -wrap2pi(-π) == π holds too, right? (Warning: it does not.) Also, from your nine test cases, only one uses the Irrational method.
If I may take the liberty of interpreting giordano, he’s saying that you should embrace that you are, in fact, working with floating-point numbers and be explicit about what tolerances are acceptable for you. For example, the following passes:
No. I have this function (written slightly differently) since years in my code, and it works well. I decided to move it to a common package, KiteUtils.jl, added some tests and improved it a little bit. No reason whatsoever to add another package (my project already depends on 500 packages).
Is there any particular reason why you expect the signs of the odd multiples to be conserved, or is this just a regression test of the signs you have observed?