6

特にJavaでは、adoubleが整数であるかどうかをどのように判断できますか?明確にするために、doubleに実際には分数や小数が含まれていないことをどのように判断できるかを知りたいと思います。

私は本質的に浮動小数点数の性質に関心があります。私が考えた方法(およびGoogleで見つけた方法)は、基本的に次の形式に従います。

double d = 1.0;
if((int)d == d) {
    //do stuff
}
else {
    // ...
}

私は確かに浮動小数点数とその動作の専門家ではありませんが、格納は数値の近似値doubleのみを格納するため、条件は一部の時間(おそらく大部分の時間)にしか入力されないという印象を受けます)。しかし、システムに値がどのように格納されているかに関係なく、100%の時間で機能することが保証されている方法を探しています。if()double

これは可能ですか?もしそうなら、どのようにそしてなぜ?

4

5 に答える 5

10

double小さな整数や(負または正の)2の累乗など、特定の値の正確な表現を格納できます。

実際に正確な整数が格納されている場合は、正常に機能し((int)d == d)ます。実際、32ビット整数iの場合(int)((double)i) == i、doubleはそれを正確に表すことができるためです。

非常に大きな数(大きさが約2 ** 52より大きい)の場合、小数部分を格納できなくなるため、doubleは常に整数のように見えることに注意してください。longこれは、たとえばJavaにキャストしようとしている場合に影響します。

于 2012-08-22T16:48:30.627 に答える
2
if(new BigDecimal(d).scale() <= 0) {
    //do stuff
}
于 2012-08-22T16:56:21.643 に答える
2

どうですか

 if(d % 1 == 0)

これは、すべての整数が1を法として0であるために機能します。

編集遅いという理由でこれに反対するすべての人に、私はそれをプロファイリングしました、そしてそれがキャストより約3.5倍遅いことがわかりました。これがタイトなループにない限り、これはテスト対象が非常に明確であり、整数キャストのセマンティクスについては何も必要としないため、これがうまくいくための好ましい方法だと思います。

私はjavacの実行時間によってそれをプロファイリングしました

class modulo {
    public static void main(String[] args) {
        long successes = 0;
        for(double i = 0.0; i < Integer.MAX_VALUE; i+= 0.125) {
            if(i % 1 == 0)
                successes++;
        }
        System.out.println(successes);
    }
}

VS

class cast {
    public static void main(String[] args) {
        long successes = 0;
        for(double i = 0.0; i < Integer.MAX_VALUE; i+= 0.125) {
            if((int)i == i)
                successes++;
        }
        System.out.println(successes);
    }
}

両方とも最後に2147483647を印刷しました。
Moduloは私のマシンで189.99秒かかりました-Castは54.75秒かかりました。

于 2012-08-22T16:47:47.733 に答える
1

使用方法はif((int)d == d)、32ビット整数に対して常に機能する必要があります。最大64ビットで動作させるために、を使用できますif((long)d == d。これは、より大きなマグニチュード数を考慮することを除いて、実質的に同じです。dが最大値よりも大きいlong(または最小値よりも小さい)場合、正確な整数であることが保証されます。dが整数であるかどうかをテストする関数は、次のように作成できます。

boolean isInteger(double d){
    if(d > Long.MAX_VALUE || d < Long.MIN_VALUE){
        return true;
    } else if((long)d == d){
        return true;
    } else {
        return false;
    }
}

浮動小数点数が整数の場合、それはその整数の正確な表現です。

于 2012-08-22T16:49:57.567 に答える
-2

ダブルスは、2進指数を持つ2進小数です。特に他の値から計算された場合は、整数がdoubleとして正確に表現できるかどうかを確認することはできません。

したがって、これにアプローチする通常の方法は、整数値に「十分に近い」必要があると言うことです。十分に近いとは、通常、「X%以内」(Xはかなり小さい)を意味します。

つまり、Xが1の場合、1.98と2.02は両方とも2に十分近いと見なされます。Xが0.01の場合、十分に近いには1.9998と2.002の間にある必要があります。

于 2012-08-22T17:55:45.760 に答える