简体   繁体   English

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

[英]Java Float Precision for values between 0 and 1

I have values between 0 and 1 stored as floats. 我将0到1之间的值存储为浮点数。 I know that delta between distinguishable floats is smaller the closer the floats are to 0. Thus, I think the precision is very high in my case (as the highest possible float is 1..). 我知道可辨别的浮点数之间的差值越小,浮点数越接近0.因此,我认为在我的情况下精度非常高(因为最高浮点数为1 ..)。 How big is my epsilon that I have to consider when comparing 2 of these floats? 在比较其中两个花车时,我需要考虑多大的ε? ie how big is the gap between 1.0f and the biggest representable float that is smaller than 1.0f? 即1.0f与小于1.0f的最大可表示浮点之间的差距有多大? I am sorry if this question seems too broad/general but I could not find an answer :-(. Thanks 我很抱歉,如果这个问题看起来太广泛/一般但我找不到答案:-(谢谢

You can use the function java.lang.Math.nextAfter(float start, double direction) to help you. 您可以使用函数java.lang.Math.nextAfter(float start, double direction)来帮助您。

Call it using, in your case, nextAfter(1.0f, 0.0) . 在您的情况下,使用nextAfter(1.0f, 0.0)来调用它。 Here we're setting the direction to be less than your starting number, so it will search "backwards". 在这里,我们将direction设置为小于您的起始编号,因此它将“向后”搜索。 The resulting float is your answer. 得到的float是你的答案。

Because this function also has an overload taking a double for start , be careful to use 1.0f to denote a float literal. 因为此函数还有一个重载需要一个double start ,所以要小心使用1.0f来表示float文字。

To get the unit of resolution for a float or double value you can use Math.ulp(x) which will give you the difference between x and the next representable value. 要获得float或double值的分辨率单位,可以使用Math.ulp(x) ,它将为您提供x与下一个可表示值之间的差异。 Note: 1 has double the gap of the value immediately before 1.0 注意: 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));

prints 版画

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

You can also do arithmetic on the representable values by looking at the raw integer representations. 您还可以通过查看原始整数表示来对可表示的值进行算术运算。

eg Math.nextUp 例如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 turns -0.0 into +0.0 BTW d += 0.0d-0.0变为+0.0

Also

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

prints 版画

Infinity

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

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