[英]Math.Sin giving me weird values
我正在嘗試創建一個徑向FAB菜單,並定義所有圓的位置,我有一種算法在理論上可以正常工作,但是當我實際運行它時,Y值給了我一些奇怪的東西。我會盡快發布我的代碼
請注意,除非您需要參考值的含義,否則這部分並不是很重要
public class FABContainer : AbsoluteLayout
{
public static int NUMBER_FOR_RING = 1;
public static double ANGLE_INCREMENT = 360.0 / ((double)NUMBER_FOR_RING);
public static double CENTER_RADIUS = 100;
public static double WIDTH_MOD = 0.9;
public FABContainer()
{
this.BackgroundColor = Color.Transparent;
FAB fab = new FAB();
List<InternalFAB> internals = new List<InternalFAB>();
internals.Add(new InternalFAB(this, internals.Count)
{
});
this.Children.Add(fab);
foreach(InternalFAB f in internals) { this.Children.Add(f); };
}
}
public partial class FAB : SuaveControls.Views.FloatingActionButton
{
public FAB()
{
this.HeightRequest = FABContainer.CENTER_RADIUS;
this.WidthRequest = FABContainer.CENTER_RADIUS * FABContainer.WIDTH_MOD;
Debug.WriteLine($"CREATING NEW CENTER WITH W: {this.WidthRequest} H: {this.HeightRequest}");
this.Image = "Edit_Icon.png";
this.BackgroundColor = Color.Transparent;
this.CornerRadius = (int)this.HeightRequest;
}
}
internal class InternalFAB : SuaveControls.Views.FloatingActionButton
{
public static double DIST = 5;
public EventHandler OnClicked;
public static double radius = 80;
public InternalFAB(FABContainer container, int count)
{
this.HeightRequest = (radius);
this.WidthRequest = (radius * FABContainer.WIDTH_MOD * 0.95);
this.BackgroundColor = Color.Transparent;
int index = count + 1;
double AngleDistortion = ((double)index) * FABContainer.ANGLE_INCREMENT;
double xpos = (DIST + this.WidthRequest) * (Math.Cos((Math.PI / 180.0) * AngleDistortion));
double ypos = (DIST + this.HeightRequest) * (Math.Sin((Math.PI / 180.0) *AngleDistortion));
Debug.WriteLine($"CREATING NEW INTERNAL AT: {xpos},{ypos} from distortion {AngleDistortion}");
this.TranslationX = xpos;
this.TranslationY = ypos;
}
}
順便說一下,沒關系,但這是使用Xamarin。 從本質上講,真正重要並給我帶來問題的部分是以下部分:
double AngleDistortion = ((double)index) * FABContainer.ANGLE_INCREMENT;
double xpos = (DIST + this.WidthRequest) * (Math.Cos((Math.PI / 180.0) * AngleDistortion));
double ypos = (DIST + this.HeightRequest) * (Math.Sin((Math.PI / 180.0) *AngleDistortion));
Debug.WriteLine($"CREATING NEW INTERNAL AT: {xpos},{ypos} from distortion {AngleDistortion}");
無論出於何種原因,Y值都將返回為-2.08183080149804E-14,而不是在“完美”情況下應返回的0。 我遍歷了我的代碼,以試圖找到錯誤,但沒有結果。
如果您需要有關我的代碼的更多說明,我會立即告訴您。
您正在使用double進行浮點算術運算 。 意味着您所做的一切都是近似的。 如果您想要確切的值,則C#可能不是您的首選語言。 Mathematica支持這些類型的值。
對於這個問題,乘以85並不重要,因此我將其放在一邊,而僅研究(有效地) Math.Sin(Math.PI * 2)
。 其結果是我的機器上的-2.44921270764475E-16
。
當然,浮點算術不是精確的,但結果並非是任意的廢話。 這里發生的是,在x = 2pi附近,sin(x)≈x-2pi。 但是, Math.Sin(Math.PI * 2)
不能精確地計算2pi處的正弦,它不能,2pi是先驗的,絕對不能表示為浮點數。 正弦輸入已經稍微“關閉”,並且具有一些值v=fl(2pi)
,其中fl
將值四舍五入到最接近的可表示浮點數。 然后sin(v) ≈ v - 2pi
,因為v
在2pi附近。
因此Math.Sin(Math.PI * 2)
應大致表示我們作為參數傳遞的2 pi與實際 2 pi的距離。 根據Wolfram Alpha ,我的機器上Math.PI * 2
的准確值為6.28318530717958623199592693708837032318115234375 ...與實際 2 pi相比是-2.4492935982947063544521318645500 ...×10 ^ -16,非常接近-2.44921270764475E-16
值從以前開始。 它不完全在那兒,但足夠接近以表明它不僅僅是任意的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.