代码之家  ›  专栏  ›  技术社区  ›  Akiner Alkan

使用Java以输入的精度递增浮点数

  •  -2
  • Akiner Alkan  · 技术社区  · 4 年前

    我正在寻找最优化、最易于阅读的版本,以其自身的精度递增浮点数:

    increment(1000) should return 1001
    increment(100.1) should return 100.2
    increment(0.1) should return 0.2
    increment(0.01) should return 0.02
    increment(0.001) should return 0.002
    increment(0.0009) should return 0.0010
    increment(0.000123) should return 0.000124
    increment(increment(0.0009)) should return 0.002
    

    public static double incrementWithMover(double value){
        DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
        df.setMaximumFractionDigits(340); //340 = DecimalFormat.DOUBLE_FRACTION_DIGITS
        String valueString = df.format(value);
        String[] splitted = valueString.split("\\.");
    
        StringBuilder mover = new StringBuilder();
    
        if(splitted.length == 2){ // Floating Decimals
            int precision = splitted[1].length();
            df.setMaximumFractionDigits(precision);
            mover = new StringBuilder("0.");
            for(int i =1; i<precision; i++){
                mover.append("0");
            }
    
            mover.append("1");
        }
        else{   // Non Floating Decimals
            mover = new StringBuilder("1");
        }
    
    
        double incremented = Double.parseDouble(valueString) + Double.parseDouble(mover.toString());
        return Double.parseDouble(df.format(incremented));
    }
    

    我之所以尝试写这个方法,是因为我检查了不同的值,并试图将所有的值以各自的精度递增一

    写这样的文章最好的方法是什么 incrementFloating

    1 回复  |  直到 4 年前
        1
  •  2
  •   WJS    4 年前

    这可能对你有用。从双精度变为字符串。

    String[] vals = { "1000","1000.1", ".1", ".01", ".001", ".00123", ".0004" };
    for (String v : vals) {
        System.out.printf("%s -> %s%n", v, incrementFloating(v));
    }
    
    

    印刷品

    1000 -> 1001
    1000.1 -> 1000.2
    .1 -> 0.2
    .01 -> 0.02
    .001 -> 0.002
    .00123 -> 0.00124
    .0004 -> 0.0005
    

    方法声明

    
    public static String incrementFloating(String v) {  
        BigDecimal b = new BigDecimal(v);
        BigDecimal increment =
                BigDecimal.valueOf(1).scaleByPowerOfTen(-b.scale());
        return b.add(increment).stripTrailingZeros().toString();
    }
    
        2
  •  0
  •   rzwitserloot    4 年前

    这不是它的工作原理。

    此行上有无限多个整数值。在任意两个整数值之间,也存在无穷多个值。

    计算机不是魔法。浮点数为32位,双精度浮点数为64位。根据基本数学,一个32位数字最多只能分辨2^32个数字,即大约40亿。

    40亿是道,道小于2个无穷阶

    那怎么办 那工作呢?嗯,大约有40亿人是“幸运的”。这些数字可以用 float 没有其他的数字 他不受祝福

    float x = 0.3; 工作,或者当你跑步时会发生什么 float x = 0.1 + 0.2;

    浮点数和双精度运算会自动转换为最接近的数字。

    受祝福数字的分布是基于二进制的(所以在十进制中它们没有任何特殊意义),并且分布不均匀。例如,接近1.0时,比接近100.0时要多得多。

    这意味着错误会潜入 . 你描述的操作在这里根本没有意义。你不能用浮球或双打来做你想做的事。时期

    使用字符串,或使用BigDecimal。

    如果您感兴趣,请点击这里:

    BigDecimal bd = new BigDecimal(0.3);
    System.out.println(bd);
    > 0.299999999999999988897769753748434595763683319091796875
    

    这是最接近0.3的数字。

    所以,在双数系统中,应用你的算法, increment(0.3) 我会努力计算 0.299999999999999988897769753748434595763683319091796876 0.299999999999999988897769753748434595763683319091796875 再说一次,手术也没用。

    毫无意义。