将Double格式化为2位小数,不使用字符串

4
我正在开发一个需要精确到小数点后两位的双精度浮点数项目。通过一些数学计算,我目前已经正确舍入了大多数数字,但是如果有尾随零,则不会进行处理。我想保留这些0以得到像 0.00 这样的结果。这个列表显示在 TableView 中,因此必须按数字进行排序。我希望双精度浮点数实际上是双精度浮点数,以便可以正确排序。

是否有任何方法可以在没有使用String.format的情况下保留2个小数位?

提前感谢您的回答。


1
请问如何将 double 类型的值保留两位小数? - JohannisK
1
FYI,当在谷歌上搜索Java保留双精度小数点后两位时,第一个结果会出现。 - JohannisK
为什么使用double而不是BigDecimal? - Patricia Shanahan
6个回答

3
您可以使用DecimalFormat。
DecimalFormat df = new DecimalFormat("#.00"); 

00 = 精确到小数点后两位。

但这将给你一个String,如果你不想进行这个String-conversion,可以将其转换为double,请参考此问题,了解如何使用BigDecimal实现此目的。

在我看来,如果这不是为了学习目的,DecimalFormat就足够了。确实,在某些时刻你需要使用String进行转换,但你只会读取和存储double,并且你的排序将是正确的...


我的主要问题是这些双精度浮点数值被显示在一个TableView中。表格本身可以通过选择列进行排序——这个功能正常工作。表格单元格正在显示存储为SimpleDoubleProperty的双精度浮点数值。将其四舍五入到2位小数是正确的,但如果有尾随零,则需要找到解决方法。例如,应该显示2.50而不是2.5。 - user3806226
所以 double-String-double 是你需要的。 - Jordi Castilla

1

本回答进一步介绍了使用java.math.BigDecimal而不是double的建议。

它比double更适合此应用程序,因为每个两位小数数字在BigDecimal中都可以被精确表示。从任意一个可用double表示的值四舍五入到两个小数位可以根据多种舍入模式之一轻松完成,包括用于double算术的模式。

另一方面,它比String更好,因为自然排序顺序是数字值。

这里是一个简短的演示程序,说明了这些观点:

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Test {
  public static void main(String[] args) throws Throwable {
    List<BigDecimal> list = new ArrayList<BigDecimal>();
    double[] in = {
        3.5,
        Math.PI,
        -100.123456,
        1e6
    };
    System.out.println("Original doubles: "+Arrays.toString(in));
    for(double d : in){
      list.add(doubleToBigDecimal(d,1));
    }
    System.out.println("Before sorting: " + list);
    Collections.sort(list);
    System.out.println("After sorting: " + list);
  }

  public static BigDecimal doubleToBigDecimal(double in, int places) {
    BigDecimal result = new BigDecimal(in).setScale(2,
        BigDecimal.ROUND_HALF_EVEN);
    return result;
  }
}

输出:

Original doubles: [3.5, 3.141592653589793, -100.123456, 1000000.0]
Before sorting: [3.50, 3.14, -100.12, 1000000.00]
After sorting: [-100.12, 3.14, 3.50, 1000000.00]

0
你可以使用 DecimalFormat,只需在 DecimalFormat 的构造函数中设置所需的两位小数格式:
double d = 1.234567;
DecimalFormat df = new DecimalFormat("#.##");
System.out.print(df.format(d));

输出:

1.23

这段代码将把小数四舍五入到指定的小数位数,但如果值本身不是最小的两个小数位,其结果将不会精确到2个小数位。例如:

    double d = 1.2;
    DecimalFormat df = new DecimalFormat("#.##");
    System.out.print(df.format(d));

输出:

1.2

就像Thisaru Guruge所说和Jordi Castilla所回答的那样,你可以这样使用:

 double d = 1.2;
    DecimalFormat df = new DecimalFormat("#.00");
    System.out.print(df.format(d));

输出:

1.20

1
使用DecimalFormat("0.00")可以将0.00显示为0.0。 参考:http://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html - ThisaruG

0
你可以尝试 BigDecimal,也可以创建一个实现了Comparable接口进行排序并具有toString()方法输出值格式化为两位小数的对象。
class TableValue implements Comparable<TableValue> {

    double value;

    public TableValue(double value) {
        this.value = value;

    }

    public int compareTo(TableValue o) {
        return Double.compare(this.value, o.value);
    }


    public String toString() {
        DecimalFormat df = new DecimalFormat("0.00");
        return df.format(value);
    }
}

0

您可以使用DecimalFormat类来设置精度,只需在类构造函数中设置所需的精度即可,例如,如果您想要2位小数精度,可以这样设置:

Double total= 12.15356789;
DecimalFormat df = new DecimalFormat("##.00");

使用 format 方法格式化值

 String dx = df.format(total);

这将返回您的双精度值的字符串值,如果您想要带有格式化2个精度的Double,则使用以下代码行。
Double totalVal = Double.valueOf(df.format(total));

这将返回带有2位精度输出的Double值,例如12.15


0

双精度浮点数不够精确,BigDecimal有一个额外的属性:精度。

因此,new BigDecimal("5.20")将具有2位精度,而双精度浮点数5.20 * 10000可能与52000.0有足够大的偏差。

请注意避免使用new BigDecimal(5.20),它既不知道精度,也不够精确。

不幸的是,BigDecimal有一个COBOListic用法。


如果你认为BigDecimal本质上是精确的,请尝试使用它计算1/3。对于这种情况,它确实比double有一个优点——精确表示所有短小的十进制分数。 - Patricia Shanahan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接