对于double f,float g,如何找到最大的int i,使得i*g <= f

jdo*_*ell 6 java

更新:谢谢凯文,我的意思是<=在标题中,而不是<.

它是否正确?这是我在解决问题的尴尬时间之后所做的最好的事情:

public int candidate_answer(double f, float g) {
    int test = (int)Math.floor(f / g);
    if ((test + 1) * g <= f) {
        test++;
    }
    return test;
}
Run Code Online (Sandbox Code Playgroud)

背景:

该应用程序是一个简单的游戏,我已经接管了以前的程序员的所有权.奇怪的是,他选择在成员和参数变量中大肆混合浮动和双打,所以有很多不必要的隐式和显式转换上下.

玩家坐标为双x,y(玩家被认为是一个点).有一个浮点数TILE_SIZE,世界是一些行和列的值,还有一些通用的越界处理.假设(x,y)坐标在边界内,我试图找出用户所在的图块,基于x(获取列)或y(获取行).这就像程序员101.

WLOG,起初我只是在做col = (int)(x/TILE_SIZE).但是正如我发现的那样,例如,.5/.1f <5,因此(int)(.5/.1f) == 4,错误的答案.这导致了上述if语句和问题的表述.

然后我发现,例如,(int)(-9.999999747378752E-5 / .1f) == 0这导致我先打电话Math.floor.

但现在我不确定这种方法中潜伏的其他错误,或者最好的方法是什么.

(如果用户正处于一排或另一排的尖端,并且我们不小心绕到了错误的那一行,这似乎不是什么大问题;但真正的问题是在代码中,我们看到意外的符号变化(+, - ,0).例如,一些代码假设如果用户位于(r,c)的图块上,那么它的点实际上是由该图块几何体所包含的.当它不是时,我们会得到像当只有非负数时,负距离等等,它会导致断言触发,而循环断开等等.)

Ste*_*ein 3

我认为你应该尝试解决根本问题(.1f 距离 .1 太远),即将 TILE_SIZE 转换为双精度,或者在任何地方一致地使用浮点数。否则,您可能会遇到由整个代码中的最小舍入错误引起的类似问题。Candidate_answer 函数是一个解决原本不应该存在的问题的 hack。

聚苯乙烯

对于这个特定问题,您可能只想找到一个更稳健的公式,即仅对一个方向上的最小舍入误差不敏感。尝试将玩家放在其场地的中心,而不是放在图块边缘,因为这样很容易陷入舍入错误:

col = (int)((x + MINIMAL_STEP_SIZE / 2.0) / TILE_SIZE)
Run Code Online (Sandbox Code Playgroud)

(理想情况下,MINIMAL_STEP_SIZE/2 部分已经是 x 的一部分,而不是添加到此处)