如何在Java中将双精度位截断为仅两位小数?


Answers:


144

如果您希望将其用于显示目的,请使用java.text.DecimalFormat

 new DecimalFormat("#.##").format(dblVar);

如果需要进行计算,请使用java.lang.Math

 Math.floor(value * 100) / 100;

50
不会显示截断的3.545555555到3.54,而是四舍五入到3.55。DecimalFormat.setRoundingMode()需要设置为RoundingMode.FLOOR;
ChristianGarcía2013年

9
这对我不起作用Math.floor(9.62 * 100)/ 100给出9.61
Mani

4
使用floor截断仅适用于正值。
2015年

3
@ChristianGarcía截断正确地完成了,RoundingMode.DOWN并且RoudingMode.FLOOR总是朝着负无穷大方向取整。
2015年

46
DecimalFormat df = new DecimalFormat(fmt);
df.setRoundingMode(RoundingMode.DOWN);
s = df.format(d);

检查可用RoundingModeDecimalFormat


不解决要求截断而不是四舍五入的问题。
罗勒·布尔克

8
@BasilBourque RoundingMode.DOWN是截断的。与错误地建议底数功能的其他答案(底数仅截断正数)相比较,这对于正值和负值均正确。
2015年

1
@Dev,我纠正了。我现在看到DOWN确实对正数和负数都有截断的作用。如doc中的示例表所示。
罗勒·布尔克

23

Bit Old Forum,以上答案均不适用于正值和负值(我的意思是进行计算,只是在不舍入的情况下进行截断)。从如何在Java中将数字四舍五入到小数点后n位链接

private static BigDecimal truncateDecimal(double x,int numberofDecimals)
{
    if ( x > 0) {
        return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_FLOOR);
    } else {
        return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_CEILING);
    }
}

这种方法对我来说很好用。

System.out.println(truncateDecimal(0, 2));
    System.out.println(truncateDecimal(9.62, 2));
    System.out.println(truncateDecimal(9.621, 2));
    System.out.println(truncateDecimal(9.629, 2));
    System.out.println(truncateDecimal(9.625, 2));
    System.out.println(truncateDecimal(9.999, 2));
    System.out.println(truncateDecimal(-9.999, 2));
    System.out.println(truncateDecimal(-9.0, 2));

结果:

0.00
9.62
9.62
9.62
9.62
9.99
-9.99
-9.00

这是可扩展用于更多测试用例的答案
diego matos-keke 18/02/13

返回新的BigDecimal(x).setScale(numberofDecimals,RoundingMode.DOWN).doubleValue();
Shimon Doodkin


9

首先请注意,a double是二进制分数,并且实际上没有小数位。

如果您需要小数位,请使用BigDecimal具有setScale()截断方法的或DecimalFormat获取一个String


7

如果出于某种原因,您不想使用a BigDecimal,则可以将doubleint转换为an 来截断它。

如果要截断到Ones位置:

  • 只需转换为 int

第十位:

  • 乘以十
  • 投放到 int
  • 投射回 double
  • 并除以十。

百度广场

  • 乘以100等

例:

static double truncateTo( double unroundedNumber, int decimalPlaces ){
    int truncatedNumberInt = (int)( unroundedNumber * Math.pow( 10, decimalPlaces ) );
    double truncatedNumber = (double)( truncatedNumberInt / Math.pow( 10, decimalPlaces ) );
    return truncatedNumber;
}

在这个例子中,decimalPlaces将名额过去的那些地方,你想要去的,所以1将轮至十分之一的地方,2至百分之一,依此类推(0发到那些地方,负一层至几十等)


3
这是一个糟糕的一般解决方案。如果unroundedNumber足够大,则乘法和强制转换都将最终丢弃数据,并导致有效的随机数。它可能适用于问题中的示例,但通用解决方案应适用于任何示例double
blm 2015年

4

我认为格式化为字符串并将其转换为双精度将为您提供所需的结果。

double值将不是round(),floor()或ceil()。

一个快速的解决方法可能是:

 String sValue = (String) String.format("%.2f", oldValue);
 Double newValue = Double.parseDouble(sValue);

您可以使用sValue进行显示,也可以使用newValue进行计算。


1
它确实将我舍入到最接近的值。例如:当我这样做时,将0.018转换为0.02。
karan patel

3

也许Math.floor(value * 100) / 100吧?请注意,类似的值3.54可能没有用精确表示double


3

您可以使用NumberFormat类对象来完成任务。

// Creating number format object to set 2 places after decimal point
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(2);            
nf.setGroupingUsed(false);

System.out.println(nf.format(precision));// Assuming precision is a double type variable

3

3.545555555得到3.54。尝试以下操作:

    DecimalFormat df = new DecimalFormat("#.##");

    df.setRoundingMode(RoundingMode.FLOOR);

    double result = new Double(df.format(3.545555555);

这将= 3.54!


1

这是我使用的方法:

double a=3.545555555; // just assigning your decimal to a variable
a=a*100;              // this sets a to 354.555555
a=Math.floor(a);      // this sets a to 354
a=a/100;              // this sets a to 3.54 and thus removing all your 5's

也可以这样做:

a=Math.floor(a*100) / 100;

0

可能正在关注:

double roundTwoDecimals(double d) { 
      DecimalFormat twoDForm = new DecimalFormat("#.##"); 
      return Double.valueOf(twoDForm.format(d));
}  

查看其他答案。如果答案要用浮点数表示,则无法可靠地做到这一点。
洛恩侯爵

0

快速检查是使用Math.floor方法。我创建了一种方法来检查以下两个或两个以下小数位的双精度:

public boolean checkTwoDecimalPlaces(double valueToCheck) {

    // Get two decimal value of input valueToCheck 
    double twoDecimalValue = Math.floor(valueToCheck * 100) / 100;

    // Return true if the twoDecimalValue is the same as valueToCheck else return false
    return twoDecimalValue == valueToCheck;
}

-1

我有一个稍微修改的Mani版本。

private static BigDecimal truncateDecimal(final double x, final int numberofDecimals) {
    return new BigDecimal(String.valueOf(x)).setScale(numberofDecimals, BigDecimal.ROUND_DOWN);
}

public static void main(String[] args) {
    System.out.println(truncateDecimal(0, 2));
    System.out.println(truncateDecimal(9.62, 2));
    System.out.println(truncateDecimal(9.621, 2));
    System.out.println(truncateDecimal(9.629, 2));
    System.out.println(truncateDecimal(9.625, 2));
    System.out.println(truncateDecimal(9.999, 2));
    System.out.println(truncateDecimal(3.545555555, 2));

    System.out.println(truncateDecimal(9.0, 2));
    System.out.println(truncateDecimal(-9.62, 2));
    System.out.println(truncateDecimal(-9.621, 2));
    System.out.println(truncateDecimal(-9.629, 2));
    System.out.println(truncateDecimal(-9.625, 2));
    System.out.println(truncateDecimal(-9.999, 2));
    System.out.println(truncateDecimal(-9.0, 2));
    System.out.println(truncateDecimal(-3.545555555, 2));

}

输出:

0.00
9.62
9.62
9.62
9.62
9.99
9.00
3.54
-9.62
-9.62
-9.62
-9.62
-9.99
-9.00
-3.54

-2

这为我工作:

double input = 104.8695412  //For example

long roundedInt = Math.round(input * 100);
double result = (double) roundedInt/100;

//result == 104.87

我个人喜欢这个版本,因为它实际上是对数字进行舍入,而不是通过将其转换为String(或类似形式)然后对其进行格式化。


1
最初的问题是关于截断,而不是舍入。同样,如果双精度数足够大,则将双精度数转换为长整数根本不会很好。
blm 2015年

-2
//if double_v is 3.545555555
String string_v= String.valueOf(double_v);
int pointer_pos = average.indexOf('.');//we find the position of '.'
string_v.substring(0, pointer_pos+2));// in this way we get the double with only 2 decimal in string form
double_v = Double.valueOf(string_v);//well this is the final result

好吧,这可能有点尴尬,但是我认为它可以解决您的问题:)


这段代码可以完成工作,但是它并不优雅并且性能很差。在学校项目中这可能还可以,但是绝对不是一个人可以在任何系统的生产中使用的解决方案,除非您以后要头痛。
cbaldan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.