3

Quick question about the sine function in Java. Does anyone know how the value is computed? I found this question about sin in Java, but that's asking why the sin function isn't wrapped in native code. I'm asking something entirely different. I want to know how the function was implemented. (Since it's wrapped in native code, I can't see it.)

Did they simply implement it from the Taylor series expansion:

sin(x) = x - (x^3)/3! + (x^5)/5! - O(x^7)

I can't look at the code for the Math.sine() function, since it gets wrapped up in native code.

Community
  • 1
  • 1
Sal
  • 3,179
  • 7
  • 31
  • 41
  • Math.PI is a constant. – Elliott Frisch Oct 01 '14 at 16:39
  • 1
    Try Googling for "fdlibm source". The definition of `sin(x)` in `StrictMath` is supposed to use the same algorithms as that library. For non-strict math, it's entirely possible that `sin` uses something on your computer's floating-point processor (depending on the hardware), so you'd have to look for hardware info to find out the exact algorithm. – ajb Oct 01 '14 at 16:39
  • 1
    Search for `sin` [here](http://developer.classpath.org/doc/java/lang/StrictMath-source.html). – Sergey Kalinichenko Oct 01 '14 at 16:41
  • @Sal Check this : http://stackoverflow.com/questions/17410559/why-does-math-sin-delegate-to-strictmath-sin – Alboz Oct 01 '14 at 16:45
  • Also, I think that mathematicians have calculated approximations things like this as polynomials with known coefficients for a long time. Babbage's Difference Engine was going to use this to generate log and trig tables. If you're ever in Northern California, visit the Computer History Museum in Mountain View--they've actually built a working Difference Engine and give demos. – ajb Oct 01 '14 at 16:46
  • Taylor series wind up being a not-great way to evaluate known special functions to limited precision. The point of a Taylor series is to give the best possible approximation on an infinitesimal neighbourhood of the point about which you expanded the series, whereas we're interested in best approximations on an interval. – tmyklebu Oct 01 '14 at 16:48
  • @Alboz Thanks for the heads up. I checked that question, but it seems more centered around the why. As in, why is the sine function not native, but the immediate inner call is native. I was more concerned with how it's implemented. – Sal Oct 01 '14 at 16:49
  • @dasblinkenlight Thanks for the link. I ran a few numbers, and this seems to be the exact function Java uses in it's native code. – Sal Oct 01 '14 at 16:52

1 Answers1

9

The implementation can be found here(*).

The sin function is approximated by a 13-degree polynomial. That is, a function on the shape

       c12x12 + c11x11 + ... + c1x1 + c0x0

on the interval [0,π/4]

The description of the algorithm looks as follows:

33 * Algorithm
34 *      1. Since sin(-x) = -sin(x), we need only to consider positive x.
35 *      2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0.
36 *      3. sin(x) is approximated by a polynomial of degree 13 on
37 *         [0,pi/4]
38 *                               3            13
39 *              sin(x) ~ x + S1*x + ... + S6*x
40 *         where
41 *
42 *      |sin(x)         2     4     6     8     10     12  |     -58
43 *      |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x  +S6*x   )| <= 2
44 *      |  x                                               |
45 *
46 *      4. sin(x+y) = sin(x) + sin'(x')*y
47 *                  ~ sin(x) + (1-x*x/2)*y
48 *         For better accuracy, let
49 *                   3      2      2      2      2
50 *              r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
51 *         then                   3    2
52 *              sin(x) = x + (S1*x + (x *(r-y/2)+y))
53 */

(*) Disclamer: Talking about OpenJDK here

aioobe
  • 413,195
  • 112
  • 811
  • 826
  • 2
    I think sin is an intrinsic method so it probably calls directly a sin CPU instruction if available and that code is unlikely to be run. – assylias Oct 01 '14 at 16:50
  • +1. I'd be surprised if it's not :-) – aioobe Oct 01 '14 at 16:50
  • Actually, unless your jvm has an option to relax java spec compliance, it probably can't use an intrinsic -- the java spec requires that sin be implemented in this exact way with this (bit-exact) precision. If your hardware has a builtin fast sin instruction that is more accurate, it can't be used without violating strict conformance. – Chris Dodd Oct 01 '14 at 17:43
  • @ChrisDodd It depends on whether you're using `StrictMath.sin` or `Math.sin`. The former has a requirement that it be implemented in an exact way; the latter does not. – ajb Oct 01 '14 at 19:41