简体   繁体   English

奇怪的浮点错误?

[英]Weird floating point error?

I've been trying to generate a pattern of circles using a for loop. 我一直在尝试使用for循环生成圆形图案。 However, when it runs everything looks fine except for the 9th ring of circles which is ever so slightly. 但是,当它运行时,除了第9圈之外,其他一切看起来都不错。 Having looked at a print out of numbers for that circle everything looks fine, so I can't work out what is going wrong. 看完那个圆圈的数字打印件后,一切看起来都很好,所以我无法弄清楚出了什么问题。 However, when I add one to the angle value of that ring. 但是,当我向该环的角度值加上一个时。 ie j (the commented out code) it pretty much corrects. 即j(已注释掉的代码)几乎可以纠正。

Any idea why this might happen. 知道为什么会发生这种情况。 having looked at all the numbers I can only think it is some math error that I haven't factored in or am I missing something obvious. 查看所有数字后,我只能认为这是我没有考虑到的数学错误,或者我错过了明显的错误。

Thanks! 谢谢!

OCD触发警告

          ellipse(325,325,15,15);      
          float div = 1;
          for (int i = i; i < 25; i++)
          {
            div = i*6
            float segment = 360/div;
            float radius = (i*20);
            for (int j = 0; j < 360; j+=segment)
            {
              //if (i==8)
              //{
                //println("before " + j);
                //j+=1;
                //println("after " + j);
              //}
              float x = 325 + (radius*cos(radians(j)));
              float y = 325 + (radius*sin(radians(j)));
              ellipse(x, y, 15, 15);
            }
          }

You get the segment as a float , but then you use an int to calculate the degrees. 您将该segment作为float ,但随后使用int来计算度数。

for (int j=0; j < 360; j+=segment)

and

float x = 325 + (radius*cos(radians(j)));

This is what is causing the rounding errors. 这就是导致舍入错误的原因。

And if you make i to get a value bigger than 60 the program will never end. 而且,如果您使i获得的值大于60该程序将永远不会结束。

Ok, three things, in order of importance. 好的,按照重要性的顺序,有三件事。 Two of these have already been mentioned. 其中两个已经被提及。

1) Clean out the int s. 1)清理出int秒。 Variable i can be an int , but none of the others (especially j since it is an angle, not a counter or index), and you want to make sure that all math operations treat numbers as double s. 变量i可以是int ,但不能是其他int (尤其是j因为它是一个角度,而不是计数器或索引),并且您需要确保所有数学运算都将数字视为double Go so far as to designate your constants as double s (eg use 1d instead of 1 ). 尽可能将常量指定为double (例如,使用1d代替1 )。

2) Avoid cumulative errors. 2)避免累积错误。 In your inner for loop, you repeatedly add to j . 在内部for循环中,您反复添加到j Bad. 坏。 Instead, compute your angle directly based on which circle you're computing. 而是直接根据要计算的圆来计算角度。

3) Use double , not float . 3)使用double ,而不是float You'll get better precision. 您将获得更好的精度。

I'd do it like this... 我会这样...

ellipse(325,325,15,15);      
for (int i = i; i < 25; i++)
{
  double div = i*6d;
  double radius = (i*20d);
  for (int j = 0; j < div; j++)
  {
    double theta = j * 360d / div;
    double x = 325d + (radius*cos(radians(theta)));
    double y = 325d + (radius*sin(radians(theta)));
    ellipse(x, y, 15, 15);
  }
}

Use double instead of float to minimise representation error. 使用double而不是float可以最小化表示错误。

Change the for loop to reduce error. 更改for循环以减少错误。

for (int k = 0; k < div; k++) {
    int j = k * 360 / div; 

This will give you different values for j which are likely to be more correct. 这将为您提供j不同值,这可能更正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM