2016-10-21 6 views
2

浮動小数点数として0〜1の値が格納されています。 浮動小数点数が0に近いほど区別可能な浮動小数点間のデルタは小さくなることがわかります。したがって、私の場合は精度が非常に高いと思います。これらのフロートのうち2つを比較する際に考慮する必要があるイプシロンはどれくらいの大きさですか?つまり、1.0fと1.0fより小さい最大の表現可能な浮動小数点の間のギャップはどれくらい大きいのですか?この質問は、一般的な/広すぎると思われる場合、私は申し訳ありませんが、私は:-(答えを見つけることができませんでした。 おかげ0〜1の値のJava Float Precision

答えて

7

あなたはあなたを助けるために機能java.lang.Math.nextAfter(float start, double direction)を使用することができます。

あなたの場合には、使用してそれを呼び出し、得られたfloatは、あなたの答えですnextAfter(1.0f, 0.0)。ここでは、あなたの開始番号未満であるとdirectionを設定しているので、それは「後方」検索します。

この機能はまた、doublestartために取って過負荷を持っているので、あること1.0fを使用してfloatを示すように注意してくださいエルラル。

+1

-0.0を回します1.0f) 'または、通常は' float'の代わりに 'double'を使う方が良い場合は、' java.lang。 Math.nextDown(1.0) ' –

+0

私はdoubleが良いと知っていますが、私は記憶がなくなっていますので、私の目的にフロートが十分かどうかを知りたいと思います。とにかく、コメントをありがとう、Java 1.8を使用するので、それぞれの機能を使用することができます。 – schubakah

1

floatまたはdouble値の解像度単位を取得するには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 

前にも、生の整数表現を見て、表現可能な値の計算を行うことができます。

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)); 
    } 
} 

`java.lang.Math.nextDown(1.8以降を使用している場合BTW d += 0.0d+0.0

また

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

プリント

Infinity 
+1

これは良い答えです。 Upvoted。 – Bathsheba

+1

@Bathsheba hehe、あなたはとても驚きました。 ;) –