118

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

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

10.0000.

我尝试DecimalFormat使用 string ##.####,但每次都使用符号很烦人。

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

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

11 回答 11

320

您可以为此尝试BigDecimal

Double toBeTruncated = new Double("3.5789055");

Double truncatedDouble = BigDecimal.valueOf(toBeTruncated)
    .setScale(3, RoundingMode.HALF_UP)
    .doubleValue();
于 2014-02-06T07:17:32.923 回答
77

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

您必须通过BigDecimal或转换为十进制基数DecimalFormat,具体取决于您以后要对该值执行的操作。

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

于 2013-02-13T03:32:24.357 回答
67

这是一个简单的方法:

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

它将精度设置为 2 位。

如果您只想打印,请以这种方式使用它:

System.out.printf("%.2f",123.234);
于 2013-10-23T21:20:14.257 回答
26

为双精度值设置精度DecimalFormat是一种很好的技术。例如,要使用此类导入java.text.DecimalFormat并创建它的对象

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

所以它会在小数点后打印两位数,它会打印 12.79

于 2016-08-24T10:51:11.360 回答
12

这对我有用:

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);
    }
于 2017-04-03T19:46:02.833 回答
4

这是实现结果的一种有效方法,但需要注意两点。

  1. 将精度限制为“最大”N 位(不固定为 N 位)。
  2. 向下舍入数字(不四舍五入到最接近的值)。

在此处查看示例测试用例。

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 的时间。

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;
}
于 2015-03-20T21:35:15.567 回答
3

和的精度由它们的大小和doubleIEEE浮点类型的实现方式固定。float

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

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

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

于 2013-02-13T03:37:22.510 回答
2
BigDecimal value = new BigDecimal(10.0000);
value.setScale(4);
于 2014-12-16T23:17:27.703 回答
1

为了扩展@EJP,处理双打时的“精度”概念非常令人担忧。正如https://stackoverflow.com/a/3730040/390153中所讨论的,无论精度如何,您甚至都不能将 0.1 表示为双精度数,出于同样的原因,您不能以有限的精度表示以 10 为底的 1/3。

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

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

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

于 2013-02-13T03:40:34.350 回答
0
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;
}
于 2013-06-23T14:23:46.090 回答
-1

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

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;
    }

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

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;
}
于 2013-10-06T14:59:06.223 回答