java处理浮点舍入误差,如何保持弧度有理

java处理浮点舍入误差,如何保持弧度有理,java,process,floating-accuracy,pi,rational-number,Java,Process,Floating Accuracy,Pi,Rational Number,我已经修改了这个arcball类,以便每次调用arcball.rollforward(PI/180);将矩阵旋转1度。 我尝试将其设置为使用累积的浮点旋转调用arcball.rollback(),其中包括floatError,但它与在没有浮点错误的情况下回滚360度具有相同的度误差。 这是1000次完全旋转后的距离,它应该是顶部立方体在x上的1:1反射 这是一个1*360度旋转循环的主要功能,用于测试的帧速率(多次旋转时将帧速率设置为900,这样就不会永远花费时间) 使用我在问题中的想法,每2

我已经修改了这个arcball类,以便每次调用arcball.rollforward(PI/180);将矩阵旋转1度。 我尝试将其设置为使用累积的浮点旋转调用arcball.rollback(),其中包括floatError,但它与在没有浮点错误的情况下回滚360度具有相同的度误差。 这是1000次完全旋转后的距离,它应该是顶部立方体在x上的1:1反射

这是一个1*360度旋转循环的主要功能,用于测试的帧速率(多次旋转时将帧速率设置为900,这样就不会永远花费时间)


使用我在问题中的想法,每2*PI重置一次

  if(keys[w]) { 
    arcball.rollforward(PI/180);
    degreeW_count = degreeW_count + 1;
  }

  if(degreeW_count == 360) {
    arcball = new Arcball(width/2, height/2, 100); // setset to original arcball at 0 degrees
    degreeW_count = 0;
  }
在电弧球中

  void rollforward(float degrees2turn) { 
    rollortilt(0, -1 * (((sin(degrees2turn) * radius))/2));  // one degree forward 180/PI
  }

这完全避免了使用无理数和周期函数的任何数据类型累积的任何舍入错误

如果您使用
double
而不是
float
(如
void rollforward(double radians2turn){
),将保持更高的精度.考虑到你所做的trig操作,它无论如何都会扩大到两倍。我想我需要一个更精确的修正,因为这只会使错误更小,而不是消除它。这就是浮点运算的本质。数字错误基本上总是存在的,所以它们会累积。跟踪累积的错误如何,这样它就不会消失可以使用相同的误差裕度进行重置,例如旋转359.9度,然后通过回滚359.9度进行重置。您可能能够比值更准确地表示错误,但您仍然受到用于存储错误的对象的精度的限制。
  void rollforward(float radians2turn) { 
    rotatebywithincludedfloaterror = rotatebywithincludedfloaterror + (-1 * (((sin(radians2turn) * radius))/2));
    if(degreeW_count >= 360) {
      arcball.rollback(rotatebywithincludedfloaterror);
      degreeW_count = 0;
      rotatebywithincludedfloaterror = 0;
    }
    rollortilt(0, -1 * (((sin(radians2turn) * radius))/2)); 
    degreeW_count = degreeW_count + 1; // need to edit this later to work with rotations other then 1 degree
  }
  if(keys[w]) { 
    arcball.rollforward(PI/180);
    degreeW_count = degreeW_count + 1;
  }

  if(degreeW_count == 360) {
    arcball = new Arcball(width/2, height/2, 100); // setset to original arcball at 0 degrees
    degreeW_count = 0;
  }
  void rollforward(float degrees2turn) { 
    rollortilt(0, -1 * (((sin(degrees2turn) * radius))/2));  // one degree forward 180/PI
  }