Java如何找到正弦和余弦?我正在努力制作一款简单的平台游戏,比如超级马里奥或恶魔城。我尝试制作一个方法,为我旋转图像,然后调整JLabel的大小以适合该图像。我找到了一个有效的算法,并且能够实现我的目标。然而,我所做的只是复制并通过算法,任何人都可以做,我想了解它背后的数学。到目前为止,除了一部分,我已经想到了一切。数学课中的方法sin和cos。他们工作,我可以使用它们,但我不知道Java如何得到它的数字。
似乎有一种方法可以解决这个问题。现在我对Java如何做到感兴趣。我查看了Taylor系列,但我不确定java是怎么做的。但是如果Java确实使用了泰勒系列,我想知道该算法是如何正确的(我知道这是一个近似值)。我也听说过CORDIC算法但是我对它的了解并不多,就像我用Taylor编写的Java系列一样,即使我不理解它。如果CORDIC是如何完成的,我想知道该算法是如何总是正确的。似乎Java方法也可能是系统相关的,这意味着所使用的算法或代码会因系统而异。如果这些方法依赖于系统,那么我想知道Windows如何获得正弦和余弦。然而,如果是CPU本身得到了答案,我想知道它正在使用什么算法(我运行AMD Turion II双核移动M520 2.29GHz)。
我查看了Math类的得分代码,它指向StrictMath类。但是StrictMath类只有一个注释,里面没有代码。我注意到该方法确实使用了关键字native。快速谷歌搜索表明,该关键字使java能够与其他语言和系统一起使用,这些语言和系统支持这些方法依赖于系统的想法。我查看了StrictMath类(http://docs.oracle.com/javase/7/docs/api/java/lang/StrictMath.html)的java api,它提到了一个名为fdlimb的东西。该链接已损坏,但我能够将其谷歌(http://www.netlib.org/fdlibm/)。
它似乎是某种用C语言编写的包。而我知道Java我从来没有学过C所以我一直无法解密它。我开始查找有关C语言的一些信息,希望能够深入了解C语言,但这是一个缓慢的过程。核心即使知道C我仍然不知道Java正在使用什么C文件。似乎有不同版本的c方法用于不同的系统,我无法分辨哪个正在使用。 API表明它是“IEEE 754核心功能”版本(驻留在名称以字母e开头的文件中)。但是我在e文件中看不到任何罪恶方法。我发现一个以k开头的,我觉得它是针对内核的,另一个以s开头,我觉得它是标准的。我发现的唯一与sin类似的e文件是e_sinh.c和e_asin.c,我认为它们是不同的数学函数。这就是我寻求用于正弦和余弦的Java算法的故事。
在该行的某个地方某个地方正在调用一个算法来获取这些数字,我想知道它是什么以及为什么它可以工作(java无法凭空捏造这些数字)。
答案 0 :(得分:3)
JDK没有义务自行计算正弦和余弦,只是为了通过Math
为您提供某些实现的接口。所以对你的问题的简单回答是:它没有;它要求做其他事情,而其他东西是依赖于平台/ JDK / JVM的。
我所知道的所有JDK都将负担转嫁给了一些本机代码。在您的情况下,您遇到了对fdlibm的引用,如果您想在那里看到实际的实现,那么您只需要吮吸它并学习阅读该代码。
有些JVM可以对此进行优化。我相信HotSpot能够发现Math.cos()
等调用,并在可用的系统上输入硬件指令,但不要引用我。
来自Math
的文档:
默认情况下,许多Math方法只是在StrictMath中调用等效方法来实现它们。鼓励代码生成器使用特定于平台的本机库或微处理器指令(如果可用),以提供更高性能的Math方法实现。此类更高性能的实现仍必须符合Math的规范。
StrictMath
的文档实际上提到了fdlibm
(它将约束放在StrictMath
上,所有函数必须产生与fdlibm
生成的结果相同的结果:
为了帮助确保Java程序的可移植性,此程序包中某些数字函数的定义要求它们产生与某些已发布算法相同的结果。这些算法可以从着名的网络库netlib获得,作为包" Freely Distributable Math Library," fdlibm。然后,这些使用C编程语言编写的算法将被理解为遵循Java浮点算法规则的所有浮点运算执行。
但请注意,Math
不需要遵从StrictMath
。如果要在所有平台上保证一致的结果,请在代码中明确使用StrictMath
。另请注意,这意味着代码生成器(例如HotSpot)无法自由优化StrictMath
对硬件调用的调用,除非硬件产生与fdlibm
完全相同的结果。
在任何情况下,Java并不是必须自己实现这些(通常不会),而且这个问题没有明确的答案。它取决于平台,JDK,在某些情况下,还取决于JVM。
对于一般的计算技术,有很多; here是一个很好的起点。 C实现通常很容易实现。如果您想了解有关特定平台上可用硬件选项的更多信息(如果Java甚至在该平台上使用它们),您必须搜索硬件数据表和文档。