1

I am wondering how Java finds sin(x). I looked at the Math.sin and it doesn't really give an answer. Please don't just say it's Taylor Series, I study math so I know it's not that simple. :)

I also checked Strict Math class and since all those JVM have different algorithms, can someone give an example on one?

So far, this is my algorithm based on Taylor series :

if( (i%4) == 0)
            suma = suma + Math.sin(x0) * Math.pow(x-x0, i) / faktorijal(i);
        if( (i%4) == 1)
            suma = suma - Math.cos(x0) * Math.pow(x-x0, i) / faktorijal(i);
        if( (i%4) == 2)
            suma = suma - Math.sin(x0) * Math.pow(x-x0, i) / faktorijal(i);
        if( (i%4) == 3)
            suma = suma + Math.cos(x0) * Math.pow(x-x0, i) / faktorijal(i);

Where x0 is the point around which I am looking for sin(x) and faktorijal is !i;

  • 2
    Possible duplicate :: http://stackoverflow.com/questions/14674306/does-anyone-know-what-the-source-code-for-the-method-math-sin-in-java-is – Justin Jasmann Aug 06 '14 at 00:57
  • See also: http://stackoverflow.com/q/14970750/1402846 – Pang Aug 06 '14 at 00:58
  • I'd guess that in a lot of cases it will be ultimately implemented by using a built-in floating-point instruction on your computer's processor, so you'd have to find the algorithm from the processor manufacturer, if available. `StrictMath` is required to use the same algorithm as the "Freely Distributable Math Library," `fdlibm`. Perhaps you could find the source code for that somewhere. – ajb Aug 06 '14 at 01:02
  • Well thanks, but looked inside those grepcode.com and haven't find solution. I am more curious about algorythm then the code it self – Gavrilo Zmaj Aleksic Aug 06 '14 at 01:08
  • "The key point seems to be that 'sin(x) is approximated by a polynomial of degree 13'." –  Aug 06 '14 at 01:17
  • Nice work but if you decrease the degree by two each time, 0 and 2 will never be possible. Only if `i%4 == 1` and `i%4 == 3` are necessary. –  Aug 06 '14 at 02:15
  • See http://stackoverflow.com/questions/2284860/how-does-c-compute-sin-and-other-math-functions. One of the answers to this states that they uses [Chebyshev_polynomials](https://en.wikipedia.org/wiki/Chebyshev_polynomials) rather than taylor series. – Salix alba Aug 06 '14 at 05:05

3 Answers3

4

It depends on the JVM implementation, but in OpenJDK, Math.sin just calls StrictMath.sin, which is implemented with a native method that calls the sine function provided by the fdlibm library.

Here's the C source code for the fdlibm sine function in OpenJDK 8:

  • s_sin.c (the sin function itself)
  • k_sin.c (the __kernel_sin function used in the implementation of sin)

The latter file has comments that describe the algorithm. The key point seems to be that "sin(x) is approximated by a polynomial of degree 13". It looks like sin transforms the x argument into an equivalent value in the range (-pi/4, +pi/4), and __kernel_sin performs a polynomial approximation that's accurate enough within that range.


Note that although the actual Java bytecode of the Math.sin method just calls StrictMath.sin, the JVM may execute Math.sin calls using other means besides actually calling the method. In particular, it's likely to to translate a Math.sin call into the corresponding native CPU instruction (such as the x86 FSIN). But a call to StrictMath.sin will always use the fdlibm implementation.

Wyzard
  • 33,849
  • 3
  • 67
  • 87
2

I'm fairly certain that java does use Taylor Series to find trigonometric values. I would imagine the functions/methods would be fairly easy to implement using modulus to move the amount degrees and radians into their respective trigonometric domains. All the rest is just Taylor Series accurate to a certain decimal point.


@Gavrilo, here's some Python 2.7 code I wrote really quick to simulate a Taylor Series sin(x) function:

from math import factorial as f
from math import sin
from math import pi

def taylorSin(n, d):
    # calculates sin(n) using a taylor-
    # polynomial of degree d

    # implement some sort of modulus to shift n in-
    # to the domain of [0, 2*pi] or [-pi, pi]

    return helper(n, d, 0)

def helper(n, d, x):
    # helper function for taylorSin(n, d)
    if d < 1:
        return x
    else:
        if d % 4 == 1:
            return helper(n, d - 2, x + float(n**d)/f(d))
        elif d % 4 == 3:
            return helper(n, d - 2, x + -1*float(n**d)/f(d))
    print 'Something screwed up'
    return None

testval = 2.13
print 'taylorSin',taylorSin(testval, 25)
print 'sin',sin(testval)

The output:

taylorSin 0.847677840134
sin 0.847677840134
  • Dude, the point with Taylor is that you can easily track down function around zero point but as you take approximation around random double value, things get rough for sin(x) and it take more than simple polynom – Gavrilo Zmaj Aleksic Aug 06 '14 at 01:10
  • @GavriloZmajAleksic No, I'm pretty sure you're thinking of MacLaurin series. MacLaurin series are Taylor Series centered at zero. Taylor Series *can* be at any random double value, and you *can* make them infinitely accurate to any decimal point using simple polynomials generated from Taylor Series. Quoting The top answer right now, "The key point seems to be that `sin(x)` is approximated by a polynomial of degree 13." –  Aug 06 '14 at 01:14
  • I understand you, and in theory it is so. But it just isn't possible to approximate sin(x) with simple polynomal function. I wrote a code and it doesn't work. – Gavrilo Zmaj Aleksic Aug 06 '14 at 01:17
  • @GavriloZmajAleksic *Yes, it is possible to approximate sin(x) with a simple polynomial function.* That's what Taylor Series do! That's the whole point of Taylor Series! They are series that can approximate non-polynomial functions using polynomials. The whole reason why Taylor Series are so famous and used so often is because they allow non-polynomial functions (like sin(x)) to be approximated with polynomial functions. You are wrong. –  Aug 06 '14 at 01:20
  • Ok, you win. Let me go back to watching at my code and figuring out where did I made mistake :) – Gavrilo Zmaj Aleksic Aug 06 '14 at 01:21
  • The problem comes to this: In taylor series i have to use the n-th derivate of function. So i'm thinking that it's not cool to say "Oh for the sin(5) i will need sin(5)" which does apear if you follow the protocol for Taylor. You get sin(x) = sin(x) + Math.sin(x0) * Math.pow(x-x0,i) / fact(i) (in the FOR loop, where x0 is the point around which you are looking) – Gavrilo Zmaj Aleksic Aug 06 '14 at 01:27
  • If you're having trouble implementing Taylor series yourself, that's a topic for a separate question. – Wyzard Aug 06 '14 at 01:34
  • @GavriloZmajAleksic I've written some Python 2.7 code if you're interested in seeing how it might be implemented. –  Aug 06 '14 at 01:46
  • Sure, send me somehow, facebook or email – Gavrilo Zmaj Aleksic Aug 06 '14 at 01:48
  • I am not that familiar with Python language but if I got it correctly, you did you Mac Loren series? Like: x - x^3/(!3) + x^5/(!5) ? – Gavrilo Zmaj Aleksic Aug 06 '14 at 02:00
  • @GavriloZmajAleksic Yes I used the MacLaurin (or Mac Loren) series. It recurses from the largest degree to 1, and finds the sign of each coefficient by using modulus. e.g., 1 % 4 == 1, 3 % 4 == 3, 5 % 4 == 1, 7 % 4 == 3. That way you can tell which terms should be positive/negative based on the degree and modulus -- if the degree % 4 is 1 or 3. –  Aug 06 '14 at 02:11
  • Ok, so it works fine up to Pi/5 (or something). Since you took MacLaurin series it means that it has to be approximated around Zero :( – Gavrilo Zmaj Aleksic Aug 06 '14 at 02:18
  • @GavriloZmajAleksic Nice! –  Aug 06 '14 at 02:19
  • But I don't like it. I want to get sin(5) i.e – Gavrilo Zmaj Aleksic Aug 06 '14 at 02:23
  • @GavriloZmajAleksic That is where you must see that 5 is not in the "standard" domain of the `sin(x)` function. So you must somehow treat 5 as a value within the "standard" domain of the `sin(x)` function, `[-pi, pi]`. `sin(5)` is equivalent to `sin(pi - 5)`, and `pi-5` is in the "standard" domain of sin. You have to implement your function such that all values are converted to respective equivalents within the "standard" domain of sin. –  Aug 06 '14 at 02:29
  • Sorry, i was stupid, just figured out that i only need to go far to sin(pi), and thanks to even function it all sorts out, thanks again :) – Gavrilo Zmaj Aleksic Aug 06 '14 at 02:36
0

The implementation details for Math are not specified.

By default many of the Math methods simply call the equivalent method in StrictMath for their implementation. Code generators are encouraged to use platform-specific native libraries or microprocessor instructions, where available, to provide higher-performance implementations of Math methods.

In other words, different JVMs can implement Math.sin differently.

But StrictMath is more formalized:

To help ensure portability of Java programs, the definitions of some of the numeric functions in this package require that they produce the same results as certain published algorithms. These algorithms are available from the well-known network library netlib as the package "Freely Distributable Math Library," fdlibm. These algorithms, which are written in the C programming language, are then to be understood as executed with all floating-point operations following the rules of Java floating-point arithmetic.

Chris Martin
  • 30,334
  • 10
  • 78
  • 137