我想知道Java如何发现sin(x)。我看了Math.sin
并没有给出答案。请不要只是说它的泰勒系列,我学习数学所以我知道它并不那么简单。 :)
我还检查了Strict Math类,因为所有这些JVM都有不同的算法,有人可以举一个例子吗?
到目前为止,这是我基于泰勒系列的算法:
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);
其中x0是我寻找罪(x)和faktorijal的地方!i;
答案 0 :(得分:4)
这取决于JVM实现,但在OpenJDK中,Math.sin
只调用StrictMath.sin
,它使用调用{{3}提供的正弦函数的本机方法实现库。
以下是OpenJDK 8中fdlibm正弦函数的C源代码:
后一个文件包含描述算法的注释。关键点似乎是“sin(x)
近似为13阶多项式”。看起来sin
将x
参数转换为范围内的等效值(-pi / 4,+ pi / 4),而__kernel_sin
执行的多项式近似在此范围内足够准确范围。
请注意,虽然Math.sin
方法的实际Java字节码只调用StrictMath.sin
,但JVM可以使用除实际调用方法之外的其他方法执行Math.sin
调用。特别是,它可能会将Math.sin
调用转换为相应的本机CPU指令(例如x86 FSIN
)。但是对StrictMath.sin
的调用将始终使用fdlibm实现。
答案 1 :(得分:2)
我非常确定java 使用Taylor Series来查找三角函数值。我可以想象,使用模数将函数/方法移动到它们各自的三角域中,函数/方法相当容易实现。所有其余的只是泰勒级数精确到一定的小数点。
@Gavrilo,这里有一些Python 2.7代码我写的很快就模拟了Taylor Series sin(x)
函数:
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)
输出:
taylorSin 0.847677840134
sin 0.847677840134
答案 2 :(得分:0)
未指定Math
的实施细节。
默认情况下,许多
Math
方法只是在StrictMath
中调用等效方法来实现它们。鼓励代码生成器使用特定于平台的本机库或微处理器指令(如果可用),以提供Math
方法的更高性能实现。
换句话说,不同的JVM可以以不同的方式实现Math.sin
。
但是StrictMath更正式化了:
为了帮助确保Java程序的可移植性,此程序包中某些数字函数的定义要求它们产生与某些已发布算法相同的结果。这些算法可以从众所周知的网络库netlib获得,作为“Freely Distributable Math Library”包fdlibm。然后,这些使用C编程语言编写的算法将被理解为遵循Java浮点算法规则的所有浮点运算执行。