簡體   English   中英

C#中的Math.Cos和Math.Sin

[英]Math.Cos & Math.Sin in C#

我正在嘗試一些我認為應該相當簡單的事情。 我有一個角度,一個位置和一個距離,我想從這些信息中找到X,Y坐標。

使用90度的示例輸入,我使用以下代碼將值轉換為弧度:

public double DegreeToRadian(float angle)
{
  return Math.PI * angle / 180.0;
}

這給了我1.5707963267949弧度然后當我使用

Math.Cos(radians)

我最終得到了一個答案:6.12303176911189E-17

到底他媽發生了什么? 90度的余弦應該是0,所以為什么我會得到這樣的偏差...更重要的是我怎么能阻止它呢?

讓我用另一個回答你的問題:你認為6.12303176911189E-17從0開始有多遠? 您所謂的偏差實際上是由於浮點數在內部存儲的方式。 我建議你閱讀以下文章 在.NET中,它們使用IEEE 754標准存儲。

見上面的答案。 請記住,6.12303176911189E-17是0.00000000000000006(我甚至可能錯過了零!)所以這是一個非常非常小的偏差。

閱讀浮點運算 它永遠也永遠不會是精確的。 永遠不要與任何東西完全比較,但要檢查數字是否因(小)epsilon而不同。

由於計算結果非常接近0(零),您可以使用舍入:

Math.Round(result, 4): // 4 decimals, e.g.: 2.1234

所以, 從弧度計算sin / cos

const double Deg = Math.PI / 180;
double sin = Math.Round(Math.Sin(yourRadianValue * Deg), 4);
double cos = Math.Round(Math.Cos(yourRadianValue * Deg), 4); // 0.0000...06 becomes 0

如果yourRadianValue = 90 ,則返回sin = 1cos = 0

其他帖子對於使用浮點實現的實際問題是正確的,這些實現返回小錯誤的結果。 但是,如果浮點庫實現保留了眾所周知的函數的基本身份,那將是很好的:

equal 0 , Math.Sin(Math.PI) 等於0
equal -1 , Math.Cos(Math.PI) 等於-1
equal 1 , Math.Sin(Math.PI/2) 等於1
equal 0 , etc. Math.Cos(Math.PI/2) 等於0 ,等等。

您可以預期浮點庫會尊重這些和其他三角恆等式 ,無論其常量值中的微小錯誤如何(例如Math.PI)。

您從Math.Cos(Math.PI/2)獲得一個小錯誤的事實表明該實現正在計算結果,而不是從表中提取它。 對於特定身份,更好地實現Math.Cos和其他超越函數可能更准確。

我確信在C#的情況下,這種行為是預期的,因此Microsoft無法在不影響現有代碼的情況下對其進行更改。 如果獲得特定三角標識的精確結果對您很重要,則可以使用一些檢查已知輸入的代碼來包裝本機浮點函數。

你應該使用四舍五入

var radians = Math.PI * degres / 180.0;
var cos = Math.Round(Math.Cos(radians), 2);
var sin = Math.Round(Math.Sin(radians), 2);

結果將是:sin:1 cos:0

正如@ b1tw153所注意到的那樣,如果為PI / 2的倍數返回了精確值,那就太好了。 而這正是微軟在他們的System.Numerics庫中所做的事情; 如果您檢查Matrix3x2.CreateRotation的源代碼,您會注意到他們手動處理n * PI / 2個案例: https//github.com/Microsoft/referencesource/blob/master/System.Numerics/System/Numerics/Matrix3x2的.cs#L325

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM