Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


How does java find sine and cosine?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
8 replies to this topic

#1 Terabyte88   Members   -  Reputation: 117

Like
0Likes
Like

Posted 02 April 2014 - 05:31 PM

Ok this question has been bugging me for months now. How does java find sine and cosine? I’m working on trying to make a game that is a simple platformer something like super Mario or Castlevania. I attempted to make a method that would rotate an image for me and then resize the JLabel to fit that image. I found an algorithm that worked and was able to accomplish my goal. However all I did was copy and past the algorithm any one can do that I want to understand the math behind it. So far I have figured everything out except one part. The methods sin and cos in the math class. They work and I can use them but I have no idea how java get its numbers.

 

It would seem there is more then one way to solve this problem for now I’m interested in how java does it. I looked into the taylor series but I’m not sure that is how java does it. But if java does use the taylor series I would like to know how that algorithm is right all the time (I am aware that it is an approximation). I’ve also heard of the CORDIC algorithm but I don’t know much about it as I do with the taylor series which I have programmed into java even though I don’t understand it. If CORDIC is how its done I would like to know how that algorithm is always right. It would seem it is also possible that the java methods are system dependent meaning that the algorithm or code used would differ from system to system. If the methods are system dependent then I would like to know how Windows gets sine and cosine. However if it is the CPU itself that gets the answerer I would like to know what algorithm it is using(I run an AMD Turion II Dual-Core Mobile M520 2.29GHz).

 

I have looked at the score code of the Math class and it points to the StrictMath class. However the StrictMath class only has a comment inside it no code. I have noticed though that the method does use the keyword native. A quick Google search suggest that this keyword enables java to work with other languages and systems supporting the idea that the methods are system dependent. I have looked at the java api for the StrictMath class (http://docs.oracle.com/javase/7/docs/api/java/lang/StrictMath.html) and it mentions something called fdlimb. The link is broken but I was able to Google it (http://www.netlib.org/fdlibm/).

 

It seems to be some sort of package written in C. while I know java I have never learned C so I have been having trouble deciphering it. I started looking up some info about the C language in the hopes of getting to bottom of this but it a slow process. Of cores even if did know C I still don’t know what C file java is using. There seems to be different version of the c methods for different systems and I can’t tell which one is being used. The API suggest it is the "IEEE 754 core function" version (residing in a file whose name begins with the letter e). But I see no sin method in the e files. I have found one that starts with a k which I think is sort for kernel and another that starts with an s which I think is sort for standard. The only e files I found that look similar to sin are e_sinh.c and e_asin.c which I think are different math functions. And that’s the story of my quest to fiend the java algorithms for sine and cosine.

 

Somewhere at some point in the line an algorithm is being called upon to get these numbers and I want to know what it is and why it works(there is no way java just gets these numbers out of thin air).



Sponsor:

#2 DiegoSLTS   Members   -  Reputation: 1779

Like
3Likes
Like

Posted 02 April 2014 - 07:16 PM

I've seen that you asked this same question in stack overflow and it was already answered, but I wanter to add something, an advise.

 

One big idea in programming is that you don't care about implementation of other things unless it's your code or you have to fix something on it (a bug or maybe a performance issue). Are you trying to optimize it or just learn how it's done? If you want to check if you have to optimize it, maybe it's better to run some test agains your own implementation, the code itself might give you an idea, but the only way to optimize is by doing tests. If it's just for learning... you'll waste a lot of time if you dive in every function, it doesn't sound like a good way to learn programming and even worse for some low level things like Math.cos. If you want to learn from reading code an open source projects where programming concepts are used will be a lot better.

 

But again, you sould abstract from the implementation, if your code calls Math.sin and Math.cos function the only things you need to know are what value should you send and what to expect. Your code will call the function and the current JDK implementation will be called, which can be different in different setups.

 

Anyway, a common way to implement those functions to be faster is by lookup tables, having the sin and cos value for a range of radian values and that range divided in really small steps. The values for sin and cos are pre calculated with a good algorithm to get the enough digits to be stored in a double variable, so when calling the functions the only work done is using the radian value to access some row in the table, and returning the sin or cos value from that row.



#3 fastcall22   Crossbones+   -  Reputation: 4387

Like
4Likes
Like

Posted 02 April 2014 - 07:58 PM

What are you trying to accomplish? As far as I know, the trigonometric functions are provided by the processor. The java runtime library makes the appropriate call. A typical implementation of a trigonometric function on the processor is generally a Taylor approximation.
c3RhdGljIGNoYXIgeW91cl9tb21bMVVMTCA8PCA2NF07CnNwcmludGYoeW91cl9tb20sICJpcyBmYXQiKTs=

#4 fastcall22   Crossbones+   -  Reputation: 4387

Like
7Likes
Like

Posted 02 April 2014 - 08:05 PM

Anyway, a common way to implement those functions to be faster is by lookup tables, having the sin and cos value for a range of radian values and that range divided in really small steps.

This is no longer true. It is much more costly to perform a lookup on a huge table than it is to calculate a trigonometric function.
c3RhdGljIGNoYXIgeW91cl9tb21bMVVMTCA8PCA2NF07CnNwcmludGYoeW91cl9tb20sICJpcyBmYXQiKTs=

#5 Buster2000   Members   -  Reputation: 1732

Like
1Likes
Like

Posted 03 April 2014 - 01:49 AM


DiegoSLTS, on 03 Apr 2014 - 02:16 AM, said:

Anyway, a common way to implement those functions to be faster is by lookup tables, having the sin and cos value for a range of radian values and that range divided in really small steps.

This is no longer true. It is much more costly to perform a lookup on a huge table than it is to calculate a trigonometric function.

 

This +1.  This was true back when wee were using 486s and Pentium 1s but the cache miss that using the lookup table would incur is now more expensive than the calculation.

 

As for how Java calculates sin cos etc.. You simply don't need to know.  If you want to learn the CORDIC algorithm or Taylor series to improve your own mathematical knowlege go ahead but, as far as I know the implementation of sin and cos is platform independant.  The Sun Runtime could be using CORDIC whilst Apples runtime could be using a Taylor Series.  The Windows implementation could be calculated by the OS whilst the Android implementation could be done in hardware. 

Could the results differ from system to system? yes 

Does it matter? No they'll be close enough so that you wouldn't notice.



#6 Olof Hedman   Crossbones+   -  Reputation: 2908

Like
1Likes
Like

Posted 03 April 2014 - 03:26 AM


But if java does use the taylor series I would like to know how that algorithm is right all the time (I am aware that it is an approximation).

 

The trick here is that all floating point values are approximations.

You just have to make sure your numerical solutions' error is less then the accuracy of the number, and the answer will be "exact" (as exact as it can be)


Edited by Olof Hedman, 03 April 2014 - 04:54 AM.


#7 TheChubu   Crossbones+   -  Reputation: 4581

Like
1Likes
Like

Posted 03 April 2014 - 04:55 AM

This is no longer true. It is much more costly to perform a lookup on a huge table than it is to calculate a trigonometric function.
Not in the case of Java standard Math class. It uses doubles for most of its operations, using a lookup table is actually quite faster than doing a cos/sin on a double. That's the reason why LibGDX has its own sin/cos/atan2 lookup tables (it's even worse on mobile devices).

 

Hell, IIRC that old IdTech inverse square root is faster than doing a Math.sqrt on a double. I'll should test it again sometime (Java micro benchmarks are a PITA to get right).


"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

 

My journals: dustArtemis ECS framework and Making a Terrain Generator


#8 fastcall22   Crossbones+   -  Reputation: 4387

Like
0Likes
Like

Posted 08 April 2014 - 12:48 PM

I did a bit of research, and it appears that Java SE provides two math libraries: StrictMath and Math. StrictMath uses a software implementation, whereas Math may use intrinsics as dictated by the JVM at runtime. If an intrinsic isn't available for a specific function, Math will call StrictMath's equivalent.

In short, use StrictMath if determinism is more important than speed, or use Math if speed is more important than determinism.

Edited by fastcall22, 08 April 2014 - 12:52 PM.

c3RhdGljIGNoYXIgeW91cl9tb21bMVVMTCA8PCA2NF07CnNwcmludGYoeW91cl9tb20sICJpcyBmYXQiKTs=

#9 SimonForsman   Crossbones+   -  Reputation: 6183

Like
1Likes
Like

Posted 08 April 2014 - 01:21 PM

I did a bit of research, and it appears that Java SE provides two math libraries: StrictMath and Math. StrictMath uses a software implementation, whereas Math may use intrinsics as dictated by the JVM at runtime. If an intrinsic isn't available for a specific function, Math will call StrictMath's equivalent.

In short, use StrictMath if determinism is more important than speed, or use Math if speed is more important than determinism.

 

It is up to the implementation for both classes, the only difference is the required accuracy. (StrictMath must give the exact same result on all platforms(Oracle has a reference library with a compliant software implementation). For the normal math class the error must be less than 0.5-2ulp (varies between methods in the class).

 

on x86 StrictMath uses a software implementation and Math does a software argument reduction (if you pass big arguments to your trig functions) before using the native instruction. a comliant JVM is free to handle things differently on architectures with more accurate trig instructions.


I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS