"""
wrap2pi(angle)
Limit the angle to the range -π .. π .
"""
function wrap2pi(angle)
if angle == pi
return pi
end
num2pi = floor(angle / 2π + 0.5)
angle - 2π * num2pi
end

I am now writing tests for it, and I am not sure how it should behave:

Was it intentional to be type-unstable (well it’s not type-unstable, unless your calling code is, so then in practice), for pi (as that type) to get that back? Since it doesn’t seem rather useful when used with floats, and you pay for that never true test(?).

Why are you making that function in the first place, and if, not wrapping to 0 …2pi? And either way, you might want to have your units in multiples of pi, and limit to 0…2, and use sinpi?

Faster because (no check and) no longer division, and probably still accurate enough:

function wrap2pi(angle)
num2pi = floor(angle * (1/2π) + 0.5)
angle - 2π * num2pi
end

This code passes my test without the need to add any tolerances or conversions.

# """
# wrap2pi(angle)
# Limit the angle to the range -π .. π .
# """
function wrap2pi(angle::Irrational)
if angle == π
return π
else
return wrap2pi(float(angle))
end
end
function wrap2pi(angle)
y = rem(angle, 2π)
abs(y) > π && (y -= 2π * sign(y))
return y
end