0

「1.56700000001」のような浮動小数点の不正確さを持つ文字列である JEval からの出力操作があります。最大の精度を維持するためのアプローチが必要ですが、フロートの不正確さを修正します。おそらく、間違いなく最も正確なものを作る効率的なアルゴリズムです。

私が間違っていなければ、正確なバイナリ表現を持たない double は、その場合、length() 18 の文字列で、精度 = (14 マイナス - ポイント char - 整数部分) で出力されます。

そのため、文字列が末尾のゼロなしですべてのビットを明確に使用している場合、精度 1 (最後の) 桁に丸めることができます (JEval はそれらを表示しないため、これは length() == 18 の場合を意味します)。

唯一の問題は、元の文字列が実際に期待される完全な値を持ち、丸めを行う必要がない場合です。その場合、精度が 1 桁しか失われません。このアプローチについてどう思いますか。それはより良い方法ですか?

例えば:

import java.math.BigDecimal;
import java.math.MathContext;

public class test {
    private final static int THREESHOLD = 3; // num of decimals from which 
                                             // we consider that they represent a floating 
                                             // representation inaccuracy in case every double´s 
                                             //digit is used with no traliing zeroes ending

    public static void main(String[] args){

        String[] JEvalOutput = {"1.5555000000000001", //Rounding is needed
                                "234455555.29",       //Rounding is not needed
                                "455656.45599999998", //Rounding is needed
                                "111132323232334.19", //Here there is a problem, should be rounded??? 
                                                      //Thats why we use THREESHOLD var, to distinguish when can we consider 
                                "123456789012345678"};//Rounding is not needed

        for (String aux : JEvalOutput){

            int precision = aux.length()-(aux.contains(".")?1:0); 
            if (precision==17 && aux.contains(".") && aux.length()-aux.indexOf('.')-1 >THREESHOLD) precision--;
            BigDecimal a = new BigDecimal(aux, new MathContext(precision)).stripTrailingZeros();

            System.out.println(aux + " --> " + a.toPlainString()); //Only First and Third are rounded. 
        }
    }
}

版画:

1.5555000000000001 --> 1.5555
234455555.29       --> 234455555.29
455656.45599999998 --> 455656.456
111132323232334.19 --> 111132323232334.19 //If THREESHOLD was 1, then this would be 111(...)34.2
123456789012345678 --> 123456789012345678

よりクリーンでベストプラクティスのプロフェッショナルなソリューションはありますか?

4

1 に答える 1

0

これはあなたが望むものです。どういたしまして。

BigDecimal bd = new BigDecimal("123.4566661");
DecimalFormat df = new DecimalFormat("#.0#");
System.out.println(df.format(bd));
于 2015-11-16T22:40:15.667 に答える