Are There Any Functions for Truncating a Double in Java?

Is there a Java Library function which can be used to truncate a number to an arbitrary number of decimal places? For Example.

SomeLibrary.truncate(1.575, 2) = 1.57

Thanks

1

11 Answers

Try setScale of BigDecimal like so:

public static double round(double d, int decimalPlace) {
    BigDecimal bd = new BigDecimal(d);
    bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
    return bd.doubleValue();
}
4

Incredible no one brought this up yet, Java API has had DecimalFormat for ages now for this exact purpose.

2

For most numbers, you won't be able to get an exact representation of xxx.yyyy unless you use a decimal class with guaranteed accuracy, such as BigDecimal.

1

There's one in commons-math. Check out :

public static double round(double x,
                           int scale)

It's implemented using BigDecimal, and is overloaded to allow specifying a rounding method, so you can use it to truncate, like this:

org.apache.commons.math.util.MathUtils.round(1.575, 2, 
    java.math.BigDecimal.ROUND_DOWN);

Update:

In the last version (Math3), this method is in the class Precision. org.apache.commons.math3.util.Precision.round(double x, int scale, int roundingMethod)

Simply remove the fractional portion

public double trunk(double value){ return value - value % 1; }

Use this simple function

double truncateDouble(double number, int numDigits) {
    double result = number;
    String arg = "" + number;
    int idx = arg.indexOf('.');
    if (idx!=-1) {
        if (arg.length() > idx+numDigits) {
            arg = arg.substring(0,idx+numDigits+1);
            result  = Double.parseDouble(arg);
        }
    }
    return result ;
}

I just want to add to ubuntudroid's solution. I tried it and it wouldn't round down, so I had to add

df.setRoundingMode(RoundingMode.FLOOR);

for it to work.

here is a short implementation which is many times faster than using BigDecimal or Math.pow

private static long TENS[] = new long[19];
static {
    TENS[0] = 1;
    for (int i = 1; i < TENS.length; i++) TENS[i] = 10 * TENS[i - 1];
}

public static double round(double v, int precision) {
    assert precision >= 0 && precision < TENS.length;
    double unscaled = v * TENS[precision];
    if(unscaled < Long.MIN_VALUE || unscaled > Long.MAX_VALUE) 
       return v;
    long unscaledLong = (long) (unscaled + (v < 0 ? -0.5 : 0.5));
    return (double) unscaledLong / TENS[precision];
}

Delete the assert'ions to taste. ;)

6

Actually, this sort of thing is easy to write:

public static double truncate(double value, int places) {
    double multiplier = Math.pow(10, places);
    return Math.floor(multiplier * value) / multiplier;
}

Note that it's Math.floor, because Math.round wouldn't be truncating.

Oh, and this returns a double, because that's what most functions in the Math class return (like Math.pow and Math.floor).

Caveat: Doubles suck for accuracy. One of the BigDecimal solutions should be considered first.

4

To do it 100% reliably, you'd have to pass the argument as string, not as floating-point number. When given as string, the code is easy to write. The reason for this is that

double x = 1.1;

does not mean that x will actually evaluate to 1.1, only to the closest exactly representable number.

2

created a method to do it.

public double roundDouble(double d, int places) {
    return Math.round(d * Math.pow(10, (double) places)) / Math.pow(10, (double)places);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Maya Lin-Takahashi

Maya Lin-Takahashi

Consumer Tech & Gadget Reviewer

Maya is a hardware enthusiast who tests and reviews smart home devices, smartphones, wearables, and audio gear. She focuses on practical consumer value and build quality.

Share this article
Twitter Facebook Pinterest