Javascript sin/cosin-taylor展开

Javascript sin/cosin-taylor展开,javascript,math,Javascript,Math,我写的一个函数有问题。其思想是使用taylor展开而不是js数学对象来计算sin和cosin值(在radians上操作)。以下是方程式: sin(x)=(x^1)/1!-(x^3)/3!+(x^5)/5!-(x^7)/7!+(x^9)/9!-(x^11)/11!+ cos(x) = (x^0)/0! - (x^2)/2! + (x^4)/4! - (x^6)/6! + (x^8)/8! - (x^10)/10! + ... 我知道当我键入类似于myCos(10,2)的内容时,由于迭代次数少,结

我写的一个函数有问题。其思想是使用
taylor
展开而不是
js
数学对象来计算sin和
cosin
值(在
radians
上操作)。以下是方程式:

sin(x)=(x^1)/1!-(x^3)/3!+(x^5)/5!-(x^7)/7!+(x^9)/9!-(x^11)/11!+

cos(x) = (x^0)/0! - (x^2)/2! + (x^4)/4! - (x^6)/6! + (x^8)/8! - (x^10)/10! + ...
我知道当我键入类似于
myCos(10,2)
的内容时,由于迭代次数少,结果会不准确,但是我不明白为什么(例如)
x=10
的结果在
iterNum=6
处开始变为真实,在
iterNum=80
处变为
NaN
。关键是,对于像
myCos/Sin(1-40,5-50)
(或多或少)这样的范围,函数可以工作,但对于更高的数字,结果变为NaN。不确定我的解释是否可以理解,但我希望可以理解,只要继续玩控制台中的函数,您就会看到问题所在
这是我的密码:

function power(a,n) {
    var result = 1;
    for (var i = 0; i < n; i++) {
        result = result * a;
    }
    return result;
}
function factorial(z) {
    var result = 1;
    for (var i = 1; i <= z; i++) {
        result = result * i;
    }
    return result;
}
function mySin(x, iterNum) {
    var sin = 0;
    var n = 1;
    for (var i = 0; i <= iterNum; i++) {
        sin = sin + (power(x,n)/factorial(n) - power(x,n+2)/factorial(n+2));
        n = n + 4;
    }
    console.log(sin + " = my function.");
    console.log(Math.sin(x)  + " math.sin");
}
function myCos(x, iterNum) {
    var cos = 0;
    var n = 0;
    for (var i = 0; i <= iterNum; i++) {
        cos = cos + (power(x,n)/factorial(n) - power(x,n+2)/factorial(n+2));
        n = n + 4;
    }
    console.log(cos + " = my function.");
    console.log(Math.cos(x) + " math.cos");
}
功能功率(a,n){
var结果=1;
对于(变量i=0;i对于(var i=1;i,您遇到的问题是

> Infinity/Infinity
NaN
因此,当
power
factorial
生成的值大于JavaScript的浮点数所能表示的值时,您将
NaN
添加到求和中,并传播到结果中

您应该能够通过使用

for (var i = 0; i <= iterNum; i++) {
    var member = power(x,n)/factorial(n) - power(x,n+2)/factorial(n+2);
    if (isNaN(member)) // maybe || member === 0
        break;
    sin += member;
    n += 4;
}

for(var i=0;i正弦级数的k-1项和k项之间的商具有很好的简单形式

-x*x / ( (2*k)*(2*k+1) )
这允许使用最少的浮点操作实现非常简单的实现:

function mySin(x, iterNum) {
    var mxx = -x*x;
    var sin = 1;
    var n = 0;
    var term = 1;
    for (var i = 1; i <= 2*iterNum; i++) {
        n = n + 2;
        term = term * mxx / ( n*(n+1) );
        sin = sin + term
    }
    sin = x*sin;
    console.log(sin + " = my function.");
    console.log(Math.sin(x)  + " math.sin");
}
函数mySin(x,iterNum){
var mxx=-x*x;
var-sin=1;
var n=0;
var项=1;

对于(var i=1;我纠正了基本原理和建设性的解决方案建议。此外,从整数开始,然后突然得到实数的原因是由于整数数据类型的范围。您使用的是JavaScript,这就像数据类型的变色龙。在某个点上,您的函数会产生幂或阶乘al变得太大,无法放入整数中,因此它变成了一个浮点数。从现在起,您将使用浮点数。@克里斯托夫斯基:您不需要在任何语言中将整数转换为除法的浮点数吗?不一定,或者至少是隐式的。在强类型语言中,您将定义一个接受float。然后在函数内部使用float,并将一个整数作为参数,它将被隐式转换为float。这里的一个解决方案是将至少一个操作数与
1.0
相乘,以确保给定的整数被解释为float。如果这是您的意思,我完全同意你似乎暗示,
power
factorial
将返回整数,然后需要对其进行强制转换(因为我们不需要整数除法)。如果它们已经返回浮点数,则其工作原理与JavaScript中的工作原理相同。@mkrds泰勒级数对于较大的值来说效果不太好,它最终会发散。您需要一个非常大的
iterNum
,大于您在JavaScript中仍然可以获得的有用幂和阶乘值。这就是为什么每个实际实现都使用
>首先,x=x%Math.PI
。有关阶乘和无功耗实现,请参阅,这样可以避免NaN,但不会对较大的
x
灾难性地取消非常大的项。