如何在不四舍五入的情况下在 Java 中格式化双输入?

Posted

技术标签:

【中文标题】如何在不四舍五入的情况下在 Java 中格式化双输入?【英文标题】:How do I format double input in Java WITHOUT rounding it? 【发布时间】:2015-04-05 22:00:54 【问题描述】:

我已阅读此问题Round a double to 2 decimal places 它显示了如何舍入数字。我想要的只是简单的格式,只打印两位小数。 我所拥有的和我尝试过的:

double res = 24.695999999999998;
DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " + df.format(res)); //prints 24.70 and I want 24.69
System.out.println("Total: " + String.format( "%.2f", res )); //prints 24.70

所以当我有 24.695999999999998 时,我想将其格式化为 24.69

【问题讨论】:

或许正在寻找Math.floor(double)? 如果您代表的是货币,看起来您可能是,您是否可以不使用 long 代替并代表确切的价值(以便士为单位)而不是诉诸 double 并提出浮点运算导致的误差范围? 【参考方案1】:

您需要先获取双精度值的floor - 然后对其进行格式化。

Math.floor(double)

返回小于或等于参数且等于数学整数的最大(最接近正无穷大)双精度值。

所以使用类似的东西:

double v = Math.floor(res * 100) / 100.0;

其他替代方法包括使用BigDecimal

public void test() 
    double d = 0.29;
    System.out.println("d=" + d);
    System.out.println("floor(d*100)/100=" + Math.floor(d * 100) / 100);
    System.out.println("BigDecimal d=" + BigDecimal.valueOf(d).movePointRight(2).round(MathContext.UNLIMITED).movePointLeft(2));

打印

d=0.29
floor(d*100)/100=0.28
BigDecimal d=0.29

【讨论】:

这可能会产生意想不到的结果。例如,最接近 0.29 的双精度值的精确值为 0.289999999999999980015985556747182272374629974365234375,截断为 0.28。【参考方案2】:

将数字乘以 100 并将其转换为整数。这会切断除您想要的两个小数位之外的所有小数位。将结果除以 100.00。 (24.69)。

int temp = (int)(res * 100);
double result = temp / 100.00;

或同一行代码:

double result = ((int)(res * 100)) / 100.00;

【讨论】:

【参考方案3】:

除了使用Math.floor(double) 和计算比例(例如* 100 然后/ 100.0 保留两位小数)之外,您还可以使用BigDecimal,然后您可以调用setScale(int, int) 之类的

double res = 24.695999999999998;
BigDecimal bd = BigDecimal.valueOf(res);
bd = bd.setScale(2, RoundingMode.DOWN);
System.out.println("Value: " + bd);

这也会给你(请求的)

Value: 24.69

【讨论】:

嘿@Elliott Frisch 这失败了 24.699999999999999 它将它转换为 24.70 但即使少了一个“9”它也能正确转换。当然,最后不可能有那么多“9”,但仅供参考。 花了大约 2 个小时,终于找到了这个并在几分钟内解决了它,非常感谢!!

以上是关于如何在不四舍五入的情况下在 Java 中格式化双输入?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用 java.math.BigInteger 的情况下在 Java 中处理非常大的数字

如何在不先保存的情况下在 Android 中发送 zip 文件?

如何在不使用 JNDI 的情况下在 ConnectionFactory 中指定主机、端口和通道

如何在不创建另一个新标签或新浏览器窗口的情况下在同一网页中播放 MPG 视频/音频文件?

如何在不使用 OLE 的情况下在 delphi 中将 word 文档转换为 pdf?

有没有办法在不破坏格式的情况下在 CSV 列中包含逗号?