拥有代码
public static final float epsilon = 0.00000001f;
public static final float a [] = {
-180.0f,
-180.0f + epsilon * 2,
-epsilon * 2
}
a
初始化如下:
[-180.0, -180.0, -2.0E-8]
而非期望的
[-180.0, X, Y]
如何调整epsilon
以达到预期效果? -
1)我希望float
而不是double
与之前编写的代码保持一致
2)我不希望-179.99999998
或X
的任何其他特定号码,我希望X > -180.0
但X
尽可能接近-180.0
}
3)我希望Y
尽可能接近0
,但要成为float
4)我想要-180.0 < X < Y
在我的帖子中,我没有准确说明我想要的内容。 Patricia Shanahan通过建议Math.ulp
答案 0 :(得分:3)
根据之前的答案中的建议,最佳解决方案是使用double
。但是,如果您想使用float
,则需要考虑其感兴趣区域的可用精度。此程序将您的文字epsilon
替换为与180f的最低有效位相关联的值:
import java.util.Arrays;
public class Test {
public static final float epsilon = Math.ulp(-180f);
public static final float a [] = {
-180.0f,
-180.0f + epsilon * 2,
-epsilon * 2
};
public static void main(String[] args) {
System.out.println(Arrays.toString(a));
}
}
输出:
[-180.0, -179.99997, -3.0517578E-5]
答案 1 :(得分:0)
虽然值0.00000001f
在float
的精确容量范围内,但值-180f + 0.00000001f * 2
(-179.99999998
)不 。 float
只有大约7-8个有效数字的精度,-179.99999998
至少需要11个。所以它的最低有效位被the addition operation删除,并且不精确的值最终成为-180.0f
。
只是为了好玩,here are those values in bits(n
= -180.0f
):
sign | exponent significand - -------- ----------------------- epsilon = 0 01100100 01010111100110001110111 epsilon2 = 0 01100101 01010111100110001110111 n = 1 10000110 01101000000000000000000 result = 1 10000110 01101000000000000000000
结果最终与原始-180.0f
相同。
如果您使用double
,那个问题goes away,因为您的精确度不超过double
〜15位数。
答案 2 :(得分:-2)
尝试“加倍”键。如果这还不够,请尝试“long double”。