[英]how to use DecimalFormat() to only output significant fractional digits
Given 0.01835132889570552
, the digits 1835
are significant (and might need to round up), and the digits 132889570552
are insignificant, so we don't want to put them into our user's input systems.给定
0.01835132889570552
,数字1835
很重要(可能需要四舍五入),而数字132889570552
不重要,因此我们不想将它们放入用户的输入系统。
Any digits to the left of the decimal place are significant, and the minimum number of numerals to the right of the decimal place is 4.小数点左边的数字都是有效的,小数点右边的数字最少是4位。
We need to pass this test:我们需要通过这个测试:
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));
Note that 183.5133
rounded up by 0.0001
.请注意,
183.5133
按0.0001
四舍五入。
So the question is: How to write formatInsignificantDigits()
without resorting to brute force or string surgery?所以问题是:如何在不诉诸蛮力或字符串手术的情况下编写
formatInsignificantDigits()
? I will answer my own question with a little brute force, and then we can see what others come up with.我会用一点蛮力回答我自己的问题,然后我们可以看看其他人的想法。
Not sure where this fits on the clean / brute-force continuum, but you could also make use of BigDecimal
and MathContext
to manage precision:不确定这在干净/蛮力连续统中的位置,但您也可以使用
BigDecimal
和MathContext
来管理精度:
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)));
}
The math function to answer the question "How significant are my decimal digits?"数学 function 用于回答“我的十进制数字有多重要?”这个问题is
Math.log10()
.是
Math.log10()
。 So we convert our fractions into negative logarithms, and turn them into a positive number indicating how many zeros we need to pad.因此,我们将分数转换为负对数,并将它们转换为正数,表示我们需要填充多少个零。 Then we add 4 to get all the digits, and we set that amount of precision:
然后我们加 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);
}
Does anyone have a cleaner way to do this?有没有人有更清洁的方法来做到这一点? Or a function of
DecimalFormat
that we overlooked?还是我们忽略的
DecimalFormat
的 function?
And it turns out this algorithm converts -0.03997394115
to "0.04"
, because rounding up cascaded to the left, and then DecimalFormat
lost the trailing zeros.事实证明,该算法将
-0.03997394115
转换为"0.04"
,因为向上舍入级联到左侧,然后DecimalFormat
丢失了尾随零。 That might not be acceptable in some circumstances...在某些情况下这可能是不可接受的......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.