Java Float Precision,值介于0和1之间

时间:2016-10-21 12:25:41

标签: java floating-point precision

我将0到1之间的值存储为浮点数。 我知道可辨别的浮点数之间的差值越小,浮点数越接近0.因此,我认为在我的情况下精度非常高(因为最高浮点数为1 ..)。在比较其中两个花车时,我需要考虑多大的ε?即1.0f与小于1.0f的最大可表示浮点之间的差距有多大?对不起,如果这个问题看起来太广泛/一般,但我找不到答案:-(。 感谢

2 个答案:

答案 0 :(得分:7)

您可以使用java.lang.Math.nextAfter(float start, double direction)功能来帮助您。

在您的情况下,使用nextAfter(1.0f, 0.0)来调用它。在这里,我们将direction设置为小于您的起始号码,因此它将向后搜索"。结果float是您的答案。

由于此函数对double的{​​{1}}也有过载,因此请谨慎使用start来表示1.0f字面值。

答案 1 :(得分:1)

要获得浮点值或双精度值的分辨率单位,您可以使用Math.ulp(x),这将为您提供x与下一个可表示值之间的差异。注意:1的差距是1.0

之前的两倍
float f = 1.0f, f_1 = Math.nextDown(f);
double d = 1.0, d_1 = Math.nextDown(d);

int f_1i = Float.floatToRawIntBits(f_1);
System.out.println("f_1=" + f_1 + " f_1i=" + Integer.toHexString(f_1i) + " eps=" + Math.ulp(f_1) + " nextUp=" + Math.nextUp(f_1));

int fi = Float.floatToRawIntBits(f);
System.out.println("f=" + f + " fi=" + Integer.toHexString(fi) + " eps=" + Math.ulp(f) + " nextUp=" + Math.nextUp(f));

long d_1i = Double.doubleToRawLongBits(d_1);
System.out.println("d_1=" + d_1 + " d_1i=" + Long.toHexString(d_1i) + " eps=" + Math.ulp(d_1) + " nextUp=" + Math.nextUp(d_1));

long di = Double.doubleToRawLongBits(d);
System.out.println("d=" + d + " di=" + Long.toHexString(di) + " eps=" + Math.ulp(d) + " nextUp=" + Math.nextUp(d));

打印

f_1=0.99999994 f_1i=3f7fffff eps=5.9604645E-8 nextUp=1.0
f=1.0 fi=3f800000 eps=1.1920929E-7 nextUp=1.0000001
d_1=0.9999999999999999 d_1i=3fefffffffffffff eps=1.1102230246251565E-16 nextUp=1.0
d=1.0 di=3ff0000000000000 eps=2.220446049250313E-16 nextUp=1.0000000000000002

您还可以通过查看原始整数表示来对可表示的值进行算术运算。

e.g。 Math.nextUp

public static double nextUp(double d) {
    if( Double.isNaN(d) || d == Double.POSITIVE_INFINITY)
        return d;
    else {
        d += 0.0d;
        return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +
                                       ((d >= 0.0d)?+1L:-1L));
    }
}

BTW d += 0.0d-0.0变为+0.0

另外

System.out.println(Math.ulp(Double.NEGATIVE_INFINITY));

打印

Infinity