Skip to content
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

revert to multiplication for radian-degree conversion #4114

Merged
merged 1 commit into from
Aug 20, 2013

Conversation

simonbyrne
Copy link
Contributor

I tried to be a bit too clever (or not clever enough) in 4a5161d by splitting the multiplication when converting between radians and degrees: although this method is correct for 30 degrees, on average it actually gives worse rounding:

julia> X = rand(1000);

julia> sum(abs(Float64[degrees2radians(i) - float64((big(pi)/180)*i) for i = X]))
3.2187421402252864e-16

julia> sum(abs(Float64[(pi/180)*i - float64((big(pi)/180)*i) for i = X]))
1.6530017372257122e-16

This commit reverts to using ordinary multiplication (and so sind(30) == 0.49999999999999994).

It is possible to do multiplication by irrational numbers with correct rounding, based on splitting the floats into half-precision (see Dekker (1971) for details of half-precision methods), but these methods require more computations. For example:

dpb = big(pi)/180
dp  = float64(dpb)
dph = signif(dp,26,2)
dpt = float64(dpb-dph)

# based on Veltkamp (1968), see Dekker (1971), p. 234
function degrees2radians(x)
    xh = signif(x,26,2)
    xt = x - xh
    z = x*dp
    z + ((((xh*dph - z) + xh*dpt) + xt*dph) + xt*dpt)
end

This approach could be used for any non-float-representable number, however it requires 11 floating point operations (plus a truncation), so is probably not worth it just to get the final digit correct.

StefanKarpinski added a commit that referenced this pull request Aug 20, 2013
revert to multiplication for radian-degree conversion
@StefanKarpinski StefanKarpinski merged commit f29c2bb into JuliaLang:master Aug 20, 2013
@simonbyrne
Copy link
Contributor Author

For future reference: this can be done in 6 flops + a truncation (which internally has a couple of flops, but could get optimised since they're powers of 2).

dpb = big(pi)/180
dp  = float64(dpb)
dph = signif(dp,26,2)
dpt = float64(dpb-dph)

# simplified
function degrees2radians(x)
    xh = signif(x,26,2)
    xt = x - xh
    xh*dph + (xt*dph + x*dpt)
end

However we still have to deal with the fact that we have to round before calling sin (see discussion of #4112).

@simonbyrne simonbyrne deleted the deg2rad branch March 10, 2015 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants