是否有处理有效数字的Java数字格式库?
内置的DecimalFormat仅允许您指定小数点右侧的位数。
由于将数字表示为double的限制,数字格式化需要在其中包含一定程度的舍入。 在一般情况下,舍入必须是一些有效数字(默认情况下是一个双精度),否则你的格式化双将最终显示像3.5999999而不是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位有效数字(或者我已经读过)。
这会增加很多开销(大约5 MB),但是International Components for Unicode项目有一个增强的DecimalFormat,可以很好地处理有效数字。
http://icu-project.org/apiref/icu4j/com/ibm/icu/text/DecimalFormat.html#sigdig
DecimalFormat formatter = new DecimalFormat(); formatter.setMaximumSignificantDigits( 4 ); System.out.println( formatter.format( hoursSinceLastAccident ) );
这样的解决方案呢:
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 563,3513(即’,’,在printf中表示使用组分隔符)
值得一提的是,如果它特别是Android而不是Java,那么内置的DecimalFormat
支持通过@
符号格式化重要数字。
String smallPi = new DecimalFormat("@@@").format("3.14159"); // formats number as '3.14'
我找到了这种做得很好的方法。
这是你只想打印出来的。
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));