Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过算法解决字符串化浮点舍入问题的最佳方法?(爪哇,杰瓦尔)_Java_Floating Point_Double_Rounding_Precision - Fatal编程技术网

Java 通过算法解决字符串化浮点舍入问题的最佳方法?(爪哇,杰瓦尔)

Java 通过算法解决字符串化浮点舍入问题的最佳方法?(爪哇,杰瓦尔),java,floating-point,double,rounding,precision,Java,Floating Point,Double,Rounding,Precision,我有一个来自JEval的输出操作,它是一个浮点不精确的字符串,类似于“1.5670000001”。我需要一些方法来保持最大精度,但要修正浮点不精确性。也许是一种高效的算法,它能做出最精确的结果而不会出错 若我并没有错,任何具有不精确二进制表示的double都将以长度()18的字符串形式输出,精度=(14个减号字符-整数部分) 因此,当字符串显然使用了所有不带尾随零的位时,我们可以舍入到精度为1(最后一个)的数字(因为JEval没有显示它们,这意味着当length()==18时) 唯一的问题是,如

我有一个来自JEval的输出操作,它是一个浮点不精确的字符串,类似于“1.5670000001”。我需要一些方法来保持最大精度,但要修正浮点不精确性。也许是一种高效的算法,它能做出最精确的结果而不会出错

若我并没有错,任何具有不精确二进制表示的double都将以长度()18的字符串形式输出,精度=(14个减号字符-整数部分)

因此,当字符串显然使用了所有不带尾随零的位时,我们可以舍入到精度为1(最后一个)的数字(因为JEval没有显示它们,这意味着当length()==18时)

唯一的问题是,如果原始字符串具有实际的预期完整值,并且不需要舍入,那么我们只会丢失一位精度。 你认为这种方法怎么样。这是更好的方法吗

例如:

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

有没有更干净、最佳实践、专业的解决方案?

这就是您想要的。不客气

BigDecimal bd = new BigDecimal("123.4566661");
DecimalFormat df = new DecimalFormat("#.0#");
System.out.println(df.format(bd));

是否要删除结尾处的尾随零?如1.125000,输出为1.125。参见