2016-09-08 4 views
2

私が書いた関数に問題があります。この考えは、js算術オブジェクトの代わりにtaylor拡張を使用して、sinとcosin値(radiansで動作)を計算することでした。Javascript sin/cosin taylor expansion

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になります。ポイントは、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"); 
} 
+0

NaNを回避する階乗的で無力な実装については、http://stackoverflow.com/a/22791396/3088138、http://stackoverflow.com/a/28227419/3088138を参照してください。しかし、非常に致命的なキャンセルはしません。より大きな「x」に対しては大きな項。 – LutzL

答えて

0

を使用して、それを修正することができるはずです

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"); 
} 

最小の浮動小数点演算を使用した簡単な実装実際に計算される場合、この計算における最大値は、約exp(x)のn-0.5 < = x < = n + 1.5の項である。これは引き続き値NaNにつながりますが、x>705以上にしかなりません。

1

:わからない私の説明が理解しやすいですが、問題はここで
が私のコードでいただきました!私はそれは、単に先に行くと、コンソールに機能を再生すると、youllは見ている願っていた場合powerfactorial両方のJavaScriptの浮動小数点数を表すことができるよりも大きな値を生成する際

> Infinity/Infinity 
NaN 

だから、あなたはあなたの合計にNaNを追加している、そしてそれは結果に伝播しているに実行して再。

あなたは正弦級数の項k-1とkとの商が素敵なシンプルなフォーム

-x*x/((2*k)*(2*k+1)) 

を持っている。これは非常にすることができます

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; 
} 
+0

正しい根拠と建設的な解決策の推奨事項。さらに、整数から始めて突然実数を取得する理由は、整数データ型の範囲が原因です。 JavaScriptを使用しています。これはデータ型に関するカメレオンのようなものです。ある時点で、関数または階乗の関数結果の1つが大きすぎて整数に収まらないため、代わりに浮動小数点数になります。これから浮動小数点数を扱います。 –

+0

@ChrisTophski:整数を任意の言語の浮動小数点型にキャストする必要はありませんか? – Bergi

+0

必ずしも暗黙的に、または少なくとも暗黙的にのみです。強く型付けされた言語では、floatを受け入れる関数を定義します。とにかく、関数内で浮動小数点数を使って作業し、浮動小数点数に暗黙的に変換される引数として整数を与えます。ここでの特定の問題に対する1つの解決策は、少なくとも1つのオペランドに '1.0 'を掛けることです。これは、指定された整数がfloatとして解釈されることを確認するためです。これがあなたが意味するものなら、私はあなたに完全に同意します。 –

関連する問題