125

For example I have the variable 3.545555555, which I would want to truncate to just 3.54.

Johnny
  • 1,419
  • 3
  • 13
  • 13

18 Answers18

173

If you want that for display purposes, use java.text.DecimalFormat:

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

If you need it for calculations, use java.lang.Math:

 Math.floor(value * 100) / 100;
rootmeanclaire
  • 808
  • 3
  • 13
  • 37
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
47
DecimalFormat df = new DecimalFormat(fmt);
df.setRoundingMode(RoundingMode.DOWN);
s = df.format(d);

Check available RoundingMode and DecimalFormat.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Cedric Dubourg
  • 479
  • 4
  • 2
  • Does not address the Question, which asked for truncation rather than rounding. – Basil Bourque Apr 14 '15 at 19:56
  • 8
    @BasilBourque RoundingMode.DOWN is truncation. Compare with other answers that incorrectly recommend floor functions (floor only truncates positive numbers), this works correctly for both positive and negative values. – Dev May 28 '15 at 19:09
  • 1
    @Dev I stand corrected. I see now that `DOWN` does indeed have the effect of truncation for both positive and negative numbers. As seen in examples table in [the doc](https://docs.oracle.com/javase/8/docs/api/java/math/RoundingMode.html). – Basil Bourque May 28 '15 at 20:42
30

None of the other answers worked for both positive and negative values ( I mean for the calculation and just to do "truncate" without Rounding). and without converting to string.

From the How to round a number to n decimal places in Java link

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

This method worked fine for me .

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

Results :

0.00
9.62
9.62
9.62
9.62
9.99
-9.99
-9.00
Shimon Doodkin
  • 4,310
  • 34
  • 37
Mani
  • 3,274
  • 2
  • 17
  • 27
9

Note first that a double is a binary fraction and does not really have decimal places.

If you need decimal places, use a BigDecimal, which has a setScale() method for truncation, or use DecimalFormat to get a String.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
8

Formating as a string and converting back to double i think will give you the result you want.

The double value will not be round(), floor() or ceil().

A quick fix for it could be:

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

You can use the sValue for display purposes or the newValue for calculation.

Jao Assy
  • 115
  • 2
  • 6
7

If, for whatever reason, you don't want to use a BigDecimal you can cast your double to an int to truncate it.

If you want to truncate to the Ones place:

  • simply cast to int

To the Tenths place:

  • multiply by ten
  • cast to int
  • cast back to double
  • and divide by ten.

Hundreths place

  • multiply and divide by 100 etc.

Example:

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

In this example, decimalPlaces would be the number of places PAST the ones place you wish to go, so 1 would round to the tenths place, 2 to the hundredths, and so on (0 rounds to the ones place, and negative one to the tens, etc.)

phuclv
  • 37,963
  • 15
  • 156
  • 475
Tarvis
  • 79
  • 1
  • 1
  • 3
    This is a *terrible* general solution. Both the multiply and the cast will end up throwing away data and resulting in what are effectively random numbers if `unroundedNumber` is big enough. It may work for the example in the question, but a general solution should work for any `double`. – blm Nov 14 '15 at 07:35
  • Does not work correctly on e.g. 2.28, 9.62 or 9411.3 – Dima Korobskiy Sep 03 '21 at 16:08
6

You can use NumberFormat Class object to accomplish the task.

// 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
Rushdi Shams
  • 2,423
  • 19
  • 31
5

3.545555555 to get 3.54. Try Following for this:

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

    df.setRoundingMode(RoundingMode.FLOOR);

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

This will give= 3.54!

Ankush G
  • 989
  • 9
  • 14
2

Here is the method I use:

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

This can also be done:

a=Math.floor(a*100) / 100;
spenibus
  • 4,339
  • 11
  • 26
  • 35
2

Maybe Math.floor(value * 100) / 100? Beware that the values like 3.54 may be not exactly represented with a double.

Vlad
  • 35,022
  • 6
  • 77
  • 199
  • Unforunately, there are counter-examples where this doesn't work: double value = 9411.3; System.out.println(Math.floor(value * 100) / 100); // 9411.29 – Dima Korobskiy Sep 03 '21 at 15:42
  • Does not work correctly on e.g. 2.28, 9.62 or 9411.3 – Dima Korobskiy Sep 03 '21 at 16:08
  • @DKroot: Depends on what you'd call "correctly". When you say `double value = 2.28;`, your `value` will be actually `2.279999999999999804600747665972448885440826416015625`, so after truncating you'd get a honest `2.27`. From my point of view, the problem is not with truncating, the problem is with assignment. – Vlad Sep 04 '21 at 11:49
  • 1
    I know about binary precision loss. That's why trunc() is a dangerous operation. However, by "correctly", I mean "as expected from a user/math perspective": E.g. `assert(2.28.trunc(2)) == 2.28` where `trunc(precision)` is a truncation method. For example, see this blog post (not mine): https://blog.mrhaki.com/2010/01/groovy-goodness-round-and-truncate.html – Dima Korobskiy Sep 05 '21 at 17:23
  • @DKroot: It's the line "double d = 2.28;" which behaves wrong from the naïve user's perspective. You must know that that there is no such double number as 2.28, right? My code sees 2.279999... as input, and it has no clue (and must not have!) that the argument comes from the unsound assumption that it must have actually been 2.28 decimal. The code gets the number which is strictly less than 2.28, and produces the correct result. – Vlad Sep 06 '21 at 11:23
  • @DKroot: If someone wants the number which strictly corresponds to its decimal representation, the appropriate type is e. g. [`BigDecimal`](https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html), not the binary-based `double`. But that's not the topic of the discussed question. – Vlad Sep 06 '21 at 11:27
  • @DKroot: About Groovy example from the blog post you mentioned: https://groovyide.com/cpi/share/v1/VVA7b8MgEP4rlClRLAZPlaNuHbJk7cRC4OIi4TvEo1Vk8d97dp0mZeG-x30cN0uPsRY5zPJC7iYHKTv5CcZBygtJwZ1WxMoJQqAX2ToZE0VIxcPiaUxkm3xcUyw5YK-fIqUiLE0qm6hGU-Db3JSPylICZWsuNDn4UrX4oM6QsxnhqFGjg6vYsOB3LJfvppjdnZt-773GWaPgszQ4qpcAHyZUEG-iV_2rOz7UkipansCx9uRUK7_r95s1Jo8loNCSkh89mjBwLQ7_0g9MdY_EzfGHt6gEpSa8z8pk08iLvbKreEJe0NPXZGs_ – Vlad Sep 06 '21 at 20:03
1

I used Math.floor() method and basic moving of decimal places by (100 = 2).

//3.545555555 to 3.54 by floor method
double x = 3.545555555;
double y = Math.floor(x * 100); //354
double z = y / 100; //3.54
R.E.F.
  • 37
  • 7
0

I have a slightly modified version of Mani's.

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

}

Output:

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
Community
  • 1
  • 1
HolyLance
  • 51
  • 4
0

A quick check is to use the Math.floor method. I created a method to check a double for two or less decimal places below:

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;
}
chris31389
  • 8,414
  • 7
  • 55
  • 66
0
      double value = 3.4555;
      String value1 =  String.format("% .3f", value) ;
      String value2 = value1.substring(0, value1.length() - 1);
      System.out.println(value2);         
      double doublevalue= Double.valueOf(value2);
      System.out.println(doublevalue);
  • 2
    Welcome to StackOverflow and congratulations on your first answer. While the code you posted may address the question asked by the original poster, you should add a few sentences to explain how your solution is better or more suited than the (many) other answers for some specific situations. – Patrick Dec 31 '20 at 14:26
0

double firstValue = -3.1756d;

double value1 = (((int)(Math.pow(10,3)*firstValue))/Math.pow(10,3));

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 11 '22 at 06:00
0

In this solution, this will TRUNCATE a double to only two decimal places. This solution will not ROUND OFF the double value.

double myDoubleNumber = 3.545555555;
DecimalFormat df = new DecimalFormat("#.##");
df.setRoundingMode(RoundingMode.DOWN);
double myDoubleNumberTruncated = Double.parseDouble(df.format(myDoubleNumber));
System.out.println(myDoubleNumberTruncated);

This will output 3.54

DecimalFormat("#.##") - Here, I entered two hash symbols(##) after the decimal point. Hence, this will truncate the number up to two decimal places.

This will work for both Positive & Negative values.

0

Maybe following :

double roundTwoDecimals(double d) { 
      DecimalFormat twoDForm = new DecimalFormat("#.##"); 
      return Double.valueOf(twoDForm.format(d));
}  
Ritesh Mengji
  • 6,000
  • 9
  • 30
  • 46
-2

This worked for me:

double input = 104.8695412  //For example

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

//result == 104.87

I personally like this version because it actually performs the rounding numerically, rather than by converting it to a String (or similar) and then formatting it.

Rainbow975
  • 47
  • 1
  • 2
  • 1
    The original question is about truncating, not rounding. Also, converting a double to a long won't work well at all if the double is large enough. – blm Nov 14 '15 at 07:27