Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.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_Number Formatting - Fatal编程技术网

是否有处理有效数字的Java数字格式化库?

是否有处理有效数字的Java数字格式化库?,java,number-formatting,Java,Number Formatting,内置的DecimalFormat仅允许您指定小数点右侧的位数 由于将数字表示为双精度的限制,数字格式需要在其中包含一定程度的舍入。在一般情况下,舍入必须是有效数字(默认情况下是双精度),否则格式化的双精度将显示3.599999而不是3.6 我能找到的最接近的解决方案是使用 new BigDecimal(double, new MathContext(14, RoundingMode.HALF_EVEN).stripTrailingZeros().toPlainString() 但是,这只提供了

内置的DecimalFormat仅允许您指定小数点右侧的位数

由于将数字表示为双精度的限制,数字格式需要在其中包含一定程度的舍入。在一般情况下,舍入必须是有效数字(默认情况下是双精度),否则格式化的双精度将显示3.599999而不是3.6

我能找到的最接近的解决方案是使用

new BigDecimal(double, new MathContext(14, RoundingMode.HALF_EVEN).stripTrailingZeros().toPlainString()
但是,这只提供了一种格式。如果我一般需要格式化它(组分隔符、十进制分隔符、限制位数、填充等),JDK库中没有任何内容

是否有一个通用的数字格式库可以正确处理有效数字的舍入

有人要求举例说明。假设我想格式化为4个有效数字,然后:

0.000003599999 -> 0.0000036
4.12345 -> 4.123
1234.345 -> 1234

我们通常采用的方法是四舍五入到14位,因为根据具体情况,双精度只能表示15-17位左右的有效数字(或者我已经读过了)。

这种解决方案怎么样:

double l = 34563.35129854289;
short offset = (short) Math.ceil(Math.log10(l) + 1);
short significantDigits = 10;

System.out.printf("%,." + (significantDigits - offset) + "f", l);
//String output = String.format("%,." + (significantDigits - offset) + "f", l);
输出:


34 5633513(即printf中的“,”表示使用组分隔符)

这增加了大量开销(5 MB左右),但国际Unicode组件项目有一个增强的十进制格式,可以很好地处理有效数字


我发现这样做很好

这是如果你只想打印出来的话

public String toSignificantFiguresString(BigDecimal bd, int significantFigures){
    return String.format("%."+significantFigures+"G", bd);
}
如果要将其转换为:

public BigDecimal toSignificantFigures(BigDecimal bd, int significantFigures){
    String s = String.format("%."+significantFigures+"G", bd);
    BigDecimal result = new BigDecimal(s);
    return result;
}
下面是一个实际应用的例子:

    BigDecimal bd2 = toSignificantFigures(BigDecimal.valueOf(4.12345), 4);
    BigDecimal bd3 = toSignificantFigures(BigDecimal.valueOf(1234.345), 4);
    BigDecimal bd4 = toSignificantFigures(BigDecimal.valueOf(0.000003599999), 4);

    System.out.println("bd2: " + String.format("%f",bd2));
    System.out.println("bd3: " + String.format("%f",bd3));
    System.out.println("bd4: " + String.format("%f",bd4));

值得一提的是,如果针对的是Android而不是Java,则内置的
十进制格式支持通过
@
符号格式化有效数字

String smallPi = new DecimalFormat("@@@").format("3.14159"); // formats number as '3.14'

问题是“是否有一个通用的数字格式库…”。您的解决方案既有用又有趣,但仅限于printf提供的解决方案。我们可以采取类似的方法,动态创建十进制格式,但无论哪种方法都有点像黑客,我会担心角落大小写和正确的舍入。@taotree,您可以对
String.format()
使用相同的黑客。您甚至可以在此基础上构建自己的
NumberFormat
。这可能不是最有效的方法,但是…为了更清楚,我建议您发布一些示例,说明对于给定的输入,您期望输出是什么。请注意,
新的bigdecime(double)
构造函数以及采用MathContext的版本存在精度问题。改为使用
bigdecim.valueOf(…)
。为此,我必须添加
setsignificandigitsused(true)
以确保使用有效数字。类
android.icu.text.DecimalFormat
支持“@”符号来表示有效数字,但常规
java.text.DecimalFormat
不支持。
String smallPi = new DecimalFormat("@@@").format("3.14159"); // formats number as '3.14'