如何使用DecimalFormat()只输出有效的小数位数



给定0.01835132889570552,数字1835是有效的(可能需要四舍五入(,而数字132889570552是无效的,所以我们不想将它们放入用户的输入系统中。

小数点左侧的任何数字都是有效的,小数点右侧的最小数字数为4。

我们需要通过这个测试:

assertEquals("1,835.1329", formatInsignificantDigits(1835.13288957055));
assertEquals("183.5133", formatInsignificantDigits(183.513288957055));
assertEquals("18.3513", formatInsignificantDigits(18.3513288957055));
assertEquals("1.8351", formatInsignificantDigits(1.83513288957055));
assertEquals("0.1835", formatInsignificantDigits(0.183513288957055));
assertEquals("0.01835", formatInsignificantDigits(0.0183513288957055));
assertEquals("0.001835", formatInsignificantDigits(0.00183513288957055));
assertEquals("0.0001835", formatInsignificantDigits(0.000183513288957055));

注意,183.51330.0001四舍五入。

所以问题是:如何在不诉诸暴力或字符串手术的情况下编写formatInsignificantDigits()?我会用一点蛮力来回答我自己的问题,然后我们可以看看其他人会想出什么。

不确定这在清洁/蛮力连续体中的位置,但您也可以使用BigDecimalMathContext来管理精度:

public static String formatInsignificantDigits(double value) {
DecimalFormat format = DecimalFormat.getInstance();
format.setMaximumFractionDigits(Integer.MAX_VALUE);
BigDecimal bigDecimal = new BigDecimal(value);
int wholeDigits = Math.max(bigDecimal.precision() - bigDecimal.scale(), 0);
return format.format(bigDecimal.round(new MathContext(wholeDigits + 4)));
}

回答问题的数学函数"我的十进制数字有多重要"是CCD_ 9。因此,我们将分数转换为负对数,并将其转换为正数,指示我们需要填充多少个零。然后我们加4得到所有的数字,然后我们设置精度:

public static @NonNull String formatInsignificantDigits(double input) {
DecimalFormat df = new DecimalFormat();
//noinspection NumericCastThatLosesPrecision
int digits = 4 + (int) -Math.log10(input);
df.setMaximumFractionDigits(Math.max(digits, 4));
return df.format(input);
}

有人有更干净的方法吗?还是我们忽略了DecimalFormat的一个函数?


事实证明,该算法将-0.03997394115转换为"0.04",因为向上取整级联到左侧,然后DecimalFormat丢失了尾部零。在某些情况下,这可能是不可接受的。。。

相关内容

  • 没有找到相关文章

最新更新