开发者

Are there any functions for truncating a double in java?

开发者 https://www.devze.com 2022-12-15 05:18 出处:网络
Is there a Java Library function which can be used to truncate a number to an arbitrary number of decimal places?

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

SomeLibr开发者_开发问答ary.truncate(1.575, 2) = 1.57

Thanks


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


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


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.


There's one in commons-math. Check out http://commons.apache.org/math/apidocs/org/apache/commons/math/util/MathUtils.html:

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


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.


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.


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

精彩评论

暂无评论...
验证码 换一张
取 消