【问题标题】:Math.Sin giving me weird valuesMath.Sin 给了我奇怪的值
【发布时间】:2019-03-11 21:18:34
【问题描述】:

我正在尝试创建一个径向 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。我广泛地检查了我的代码以试图找到错误,但无济于事。

如果您需要更多关于我的代码的说明,我会立即告诉您。

【问题讨论】:

  • Math.PI 只是 PI 的近似值。浮点数学并不精确。 -2E-14 非常接近 0
  • 你的意思是浮点数不是真实世界数字的精确表示?另外,我很好奇 2.0E-14 范围内的错误在哪里很重要。在现实世界中,这比亚原子距离还小。
  • 请注意,Math.Pi 完全等于 7074237752028440*2^-51

标签: c# algorithm xamarin math


【解决方案1】:

您正在与双打合作,表演floating point arithmetic。这意味着您所做的一切都是近似的。如果你想要精确的值,也许 C# 不是你的 goto 语言。 Mathematica 支持这些类型的值。

【讨论】:

    【解决方案2】:

    乘以 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 与 real 2 pi 的距离。 Math.PI * 2具有6.28318530717958623199592693708837032318115234375我的机器,according to Wolfram Alpha即-2.4492935982947063544521318645500 ...上的精确值×10 ^ -16断从实 EM> 2的PI,这是相当接近-2.44921270764475E-16 之前的值。它并不完全存在,但足够接近表明它不仅仅是任意的东西。

    【讨论】:

      猜你喜欢
      • 2021-08-06
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      • 2020-08-01
      • 2014-02-18
      • 1970-01-01
      • 1970-01-01
      • 2015-12-22
      相关资源
      最近更新 更多