java - 快速查找某个范围包含数字的方法

标签 java performance range

问题:

给定任意 double 下界、 double 上限和 double 增量,确定给定输入 double 范围的最快方法是什么?如果您不关心内存使用情况,使用预先计算或类似的方法,您是否可以比使用双除法的明显方法做得更好?注意:重复使用此类不可能得到完全相同的 double 值,换句话说,将结果缓存在 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

最佳答案

替换行:

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

这样:

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

它提供了更合理的结果,并且在我的临时基准测试中运行速度提高了约 30 倍(因为它不再循环调用)。
最好将 1e-7“epsilon”声明为常量,并可能将其值调整为您需要的误差范围。搜索浮点舍入错误(或类似的内容)以了解有关该主题的更多信息,例如 this article .

关于java - 快速查找某个范围包含数字的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18836226/

相关文章:

java - 法线贴图上的双重锁定 - 这安全吗?

java - Eclipse 断点蓝色圆圈与玻璃图标?

java - 在 Android 上解析 xml 文件时文件过早结束

java - 为什么我们在 java 中将变量声明为私有(private)

json - 为什么这个 Scala 代码很慢?

javascript - CDN 上有哪些著名的 JavaScript 库,URL 是什么?

iPhone 范围 slider

python - 使用 python,我如何合并或加入两个列表以使它们的值不重叠?

java - 当递归函数被调用时,成员变量是否仍在缓冲区中?

c++ - GCC:由于数据类型的范围有限,比较总是正确的——在模板参数中?