如何使用DecimalFormat()仅输出大量的分数数字

发布于 2025-01-21 04:20:30 字数 998 浏览 2 评论 0 原文

给定 0.01835132889570552 ,数字 1835 很重要(并且可能需要汇总),并且Digits 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.5133 。 > 0.0001 。

因此,问题是:如何编写 formatinsignificantdigits()而无需诉诸蛮力或弦乐手术?我将用一点点蛮力回答自己的问题,然后我们可以看到其他人提出了什么。

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.

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.

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.

So the question is: How to write formatInsignificantDigits() without resorting to brute force or string surgery? I will answer my own question with a little brute force, and then we can see what others come up with.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一腔孤↑勇 2025-01-28 04:20:30

不确定这适用于干净/蛮力连续性的位置,但是您也可以使用 bigdecimal MathContext 来管理Precision:

    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)));
    }

Not sure where this fits on the clean / brute-force continuum, but you could also make use of BigDecimal and MathContext to manage precision:

    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)));
    }
坏尐絯℡ 2025-01-28 04:20:30

数学功能回答“我的小数位数有多重要?” IS Math.log10()。因此,我们将分数转换为负对数,并将它们变成一个正数,指示我们需要垫子多少零。然后,我们添加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);
}

有人有更干净的方法吗?还是我们忽略的 Demalformat 的函数?


事实证明,该算法转换 -0.03997394115 “ 0.04” ,因为将圆和级别列为左侧,然后 demimalformat 丢失了落后的零件。在某些情况下,这可能是无法接受的...

The math function to answer the question "How significant are my decimal digits?" is 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:

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?


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. That might not be acceptable in some circumstances...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文