Java:如何为double值设置Precision?

Java: How to set Precision for double value?

本问题已经有最佳答案,请猛点这里访问。

我最近正在处理数字,我有一种情况,我想将双精度值的精度设置为6位或4位,这取决于数据库中存储的值。

例如,如果在数据库中,精度设置为4位,则输出必须如下所示:

10.0000

我试过使用DecimalFormat和字符串##.####,但每次使用符号都很烦人。

有没有更好的方法,比如说:

1
2
Double value = 10.0;
value.setPrecision(4);


为此,您可以尝试bigdecimal

1
2
3
4
5
Double toBeTruncated = new Double("3.5789055");

Double truncatedDouble = BigDecimal.valueOf(toBeTruncated)
    .setScale(3, RoundingMode.HALF_UP)
    .doubleValue();


这是一个简单的方法。

1
String formato = String.format("%.2f");

它将预设值设置为2位数o any。

如果你只想用这种方式打印。

1
System.out.printf("%.2f",123.234);


不能将双精度(或双精度)设置为指定的小数位数,因为浮点值没有小数位数。它们有二进制数字。

您必须转换为十进制基数,可以通过BigDecimalDecimalFormat,这取决于您以后要对该值做什么。

另请参阅我对这个问题的回答,以反驳不可避免的*100/100答案。


设定双值的精度是很好的技术。例如,使用这个类import java.text.DecimalFormat并创建它的对象

1
2
3
double no=12.786;
DecimalFormat dec = new DecimalFormat("#0.00");
System.out.println(dec.format(no));

所以它将在小数点后两位数字,这里它将打印12.79


这对我很有用:

1
2
3
4
5
public static void main(String[] s) {
        Double d = Math.PI;
        d = Double.parseDouble(String.format("%.3f", d));  // can be required precision
        System.out.println(d);
    }


这是一种通过两个警告来实现结果的有效方法。

  • 将精度限制为"最大"n位(不固定为n位)。
  • 四舍五入数字(不是四舍五入到最近的数字)。
  • 请参见此处的示例测试用例。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    123.12345678 ==> 123.123
    1.230000 ==> 1.23
    1.1 ==> 1.1
    1 ==> 1.0
    0.000 ==> 0.0
    0.00 ==> 0.0
    0.4 ==> 0.4
    0 ==> 0.0
    1.4999 ==> 1.499
    1.4995 ==> 1.499
    1.4994 ==> 1.499

    这是密码。我上面提到的两个注意事项可以很容易地解决,但是速度对我来说比准确性更重要,所以我把它放在这里。与数学运算相比,像System.out.printf("%.2f",123.234);这样的字符串操作在计算上代价很高。在我的测试中,与字符串操作相比,下面的代码(没有sysout)花费了1/30的时间。

    1
    2
    3
    4
    5
    6
    public double limitPrecision(String dblAsString, int maxDigitsAfterDecimal) {
        int multiplier = (int) Math.pow(10, maxDigitsAfterDecimal);
        double truncated = (double) ((long) ((Double.parseDouble(dblAsString)) * multiplier)) / multiplier;
        System.out.println(dblAsString +" ==>" + truncated);
        return truncated;
    }


    doublefloat的精度取决于它们的大小和实现IEEE浮点类型的方式。

    另一方面,输出中的小数位数是格式问题。你是正确的,一次又一次地输入相同的常量是个坏主意。您应该声明一个字符串常量,并使用它的符号表示。

    1
    private static final String DBL_FMT ="##.####";

    使用符号表示可以更改使用常量的所有位置的精度,而无需搜索代码。


    1
    2
    BigDecimal value = new BigDecimal(10.0000);
    value.setScale(4);

    要扩展@ejp,在处理双打时"精确"的概念是非常令人担忧的。正如在https://stackoverflow.com/a/3730040/390153中所讨论的,无论精度如何,您甚至不能将0.1表示为双精度,同样的原因是您不能以有限精度表示10进制中的1/3。

    您需要考虑要解决的问题,并考虑:

    a)我应该首先使用双打吗;如果精度是一个相关概念,那么使用双打很可能是一个错误。

    b)如果双打合适,我所说的精确是什么意思?如果你只谈论显示,把逻辑包装在一个显示函数中,你只需要在一个地方处理它,即应用干燥原理。


    也许这个方法可以帮助您精确计算双精度值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    double truncate(double number)
        {
            int integerPart = (int) number;
            double fractionalPart = number - integerPart;
            fractionalPart *= 100;  //It is for upto two decimal values after point.
                                    //You can increase the zeros to fulfill your needs.
            int fractPart = (int) fractionalPart;
            fractionalPart = (double) (integerPart) + (double) (fractPart)/100;
            return fractionalPart;
        }

    此方法将允许设置精度级别。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    double truncate(double number, int precision)
    {
        double prec = Math.pow(10, precision);
        int integerPart = (int) number;
        double fractionalPart = number - integerPart;
        fractionalPart *= prec;
        int fractPart = (int) fractionalPart;
        fractionalPart = (double) (integerPart) + (double) (fractPart)/prec;
        return fractionalPart;
    }

    1
    2
    3
    4
    5
    6
    7
    8
    public static String setPrecision(String number, int decimal) {
        double nbr = Double.valueOf(number);
        int integer_Part = (int) nbr;
        double float_Part = nbr - integer_Part;
        int floating_point = (int) (Math.pow(10, decimal) * float_Part);
        String final_nbr = String.valueOf(integer_Part) +"." + String.valueOf(floating_point);
        return final_nbr;
    }


    我在顶部看到了答案:

    1
    2
    3
    4
    Double toBeTruncated = new Double("3.5789055");
    Double truncatedDouble = BigDecimal.valueOf(toBeTruncated)
        .setScale(3, RoundingMode.HALF_UP)
        .doubleValue();

    我认为这不是一个完美的答案,因为在很多情况下,当你打电话给doubleValue()时,答案会改变。

    例:BigDecimal.valueOf(toBeTruncated).setScale(3, RoundingMode.HALF_UP)的输出为12.500,

    然后在.doubleValue()之后,输出将为12.5,即精度丢失。

    解决方案:要么使用不带.doubleValue()方法的BigDecimal类型显示,要么在最终答案后使用字符串格式。