3

浮動小数点値の丸めに関連する SO に関する多くの議論を見てきましたが、効率の側面を考慮した確固たる Q&A はありません。だからここにあります:

float 値を最も近い整数に丸める最も効率的な (しかし正しい) 方法は何ですか?

(int) (mFloat + 0.5);

また

Math.round(mFloat);

また

FloatMath.floor(mFloat + 0.5);

または、他の何か?

できれば、インポートする必要のある外部ライブラリではなく、標準の Java ライブラリで利用できるものを使用したいと考えています。

4

5 に答える 5

5

あなたが参照していると思われる Q&A に基づいて、さまざまな方法の相対的な効率は、使用しているプラ​​ットフォームによって異なります

しかし、結論は次のとおりです。

  • Math.floor最新の JRE には/のパフォーマンス修正が含まれておりStrictMath.floor
  • 非常に多くの丸めを行っていない限り、どちらの方法で行ってもおそらく違いはありません。

参考文献:

于 2012-08-23T12:02:56.737 に答える
4
public class Main {
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            measurementIteration();
        }
    }

    public static void measurementIteration() {
        long s, t1 = 0, t2 = 0;
        float mFloat = 3.3f;
        int f, n1 = 0, n2 = 0;
        for (int i = 0; i < 1E4; i++) {
            switch ((int) (Math.random() * 2)) {
            case 0:
                n1 += 1E4;
                s = System.currentTimeMillis();
                for (int k = 0; k < 1E4; k++)
                    f = (int) (mFloat + 0.5);
                t1 += System.currentTimeMillis() - s;
                break;
            case 1:
                n2 += 1E4;
                s = System.currentTimeMillis();
                for (int k = 0; k < 1E4; k++)
                    f = Math.round(mFloat);
                t2 += System.currentTimeMillis() - s;
                break;
            }
        }
        System.out.println(String.format("(int) (mFloat + 0.5): n1 = %d    -> %.3fms/1000", n1, t1 * 1000.0 / n1));
        System.out.println(String.format("Math.round(mFloat)  : n2 = %d    -> %.3fms/1000", n2, t2 * 1000.0 / n2));
    }
}

Java SE6 での出力:

(int) (mFloat + 0.5): n1 = 500410000    -> 0.003ms/1000
Math.round(mFloat)  : n2 = 499590000    -> 0.022ms/1000

Java SE7 での出力 (結果を提供してくれたalexに感謝):

(int) (mFloat + 0.5): n1 = 50120000 -> 0,002ms/1000
Math.round(mFloat) : n2 = 49880000 -> 0,002ms/1000

ご覧のとおりMath.round、SE6 から SE7 ではパフォーマンスが大幅に向上しています。SE7 ではもはや大きな違いはないと思います。読みやすいと思われるものを選択する必要があります。

于 2012-08-23T12:13:45.230 に答える
0

を使用してベンチマークすることができますSystem.currentTimeMillis()。違いが小さすぎることがわかります

于 2012-08-23T12:09:09.460 に答える
0

メソッドに丸めロジックをカプセル化しているためMath.round(mFloat)です(それがあなたのメソッドではない場合でも)。

そのドキュメントによると、あなたが書いたコードはMath.round実行されるものと同じです(ボーダーケースをチェックすることを除いて)。

とにかく、より重要なのは、小さな定数のようなものの時間ではなく、アルゴリズムの時間の複雑さです...何百万回も呼び出される何かをプログラミングしている場合を除いて! :D

編集: FloatMath を知りません。JDKからですか?

于 2012-08-23T12:02:03.027 に答える