0

質問:

任意の double の下限、double の上限、および double のインクリメントが与えられた場合、指定された入力 double の範囲を決定する最速の方法は何ですか? 事前計算などを使用して、メモリ使用量を気にしない場合、二重除算を使用する明白な方法よりもうまくいくでしょうか? 注: このクラスを繰り返し使用しても、正確に同じ double 値になるとは限りません。つまり、結果を a にキャッシュしてもMap<Double, Double>おそらく役に立たないでしょう。

率直な答え:

public class RangeFinder {
    private double lowerBound;
    private double higherBound;
    private double increment;

    public RangeFinder(double lowerBound, double higherBound, double increment) {
        if(increment < 0) throw new IllegalArgumentException("Increment cannot be negative!");
        this.lowerBound = lowerBound;
        this.higherBound = higherBound;
        this.increment = increment;
    }

    public int getRange(double number) {
        if (number < lowerBound) return 0;
        if (number > higherBound) number = higherBound;
        return (int) Math.round((number - lowerBound) / increment);
    }

    public static void main(String... args) {
        double lower = 2.3d;
        double higher = 3.9;
        double inc = 0.1d;

        double[] inputs = { 0.5d, 2.25, 2.35, 2.4, 3.0, 3.8, 3.85, 3.9, 4.0 };

        RangeFinder rf = new RangeFinder(lower, higher, inc);

        System.out.format("Lower bound: %1.2f%n", lower);
        System.out.format("Upper bound: %1.2f%n", higher);
        System.out.format("Increment: %1.2f%n", inc);

        for(double inp : inputs) {
            System.out.format("Input: %1.2f\tOutput: %d%n",
                    inp, rf.getRange(inp));
        }
    }
}

例:

Lower bound: 2.30
Upper bound: 3.90
Increment: 0.10
Input: 0.50 Output: 0
Input: 2.25 Output: 0
Input: 2.35 Output: 1
Input: 2.40 Output: 1
Input: 3.00 Output: 7
Input: 3.80 Output: 15
Input: 3.85 Output: 16
Input: 3.90 Output: 16
Input: 4.00 Output: 16
4

1 に答える 1

1

次の行を置き換えます。

return (int) Math.round((number - lowerBound) / increment);

これとともに:

return (int) ((number - lowerBound + 1e-7) / increment);

これにより、より賢明な結果が得られ、アドホック ベンチマークで約 30 倍高速に実行されます (ラウンド呼び出しが行われないため)。
1e-7 の「イプシロン」を定数として宣言し、その値を必要な誤差範囲に調整することをお勧めします。浮動小数点の丸め誤差 (または同様のもの) を検索して、この記事などの件名について詳しく調べてください。

于 2013-09-16T21:40:21.697 に答える