Есть ли функция библиотеки Java, которая может использоваться для усечения числа на произвольное число десятичных знаков? Например.
SomeLibrary.truncate(1.575, 2) = 1.57
Спасибо
Есть ли функция библиотеки Java, которая может использоваться для усечения числа на произвольное число десятичных знаков? Например.
SomeLibrary.truncate(1.575, 2) = 1.57
Спасибо
Попробуйте setScale BigDecimal следующим образом:
public static double round(double d, int decimalPlace) {
BigDecimal bd = new BigDecimal(d);
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();
}
Невероятно, что никто этого не делал, Java API уже DecimalFormat для этой цели.
Для большинства чисел вы не сможете получить точное представление xxx.yyyy
, если вы не используете десятичный класс с гарантированной точностью, например BigDecimal.
Там один в общедоступной математике. Проверьте http://commons.apache.org/math/apidocs/org/apache/commons/math/util/MathUtils.html:
public static double round(double x,
int scale)
Он реализован с использованием BigDecimal и перегружен, чтобы указать способ округления, поэтому вы можете использовать его для усечения, например:
org.apache.commons.math.util.MathUtils.round(1.575, 2,
java.math.BigDecimal.ROUND_DOWN);
Update:
В последней версии (Math3) этот метод находится в классе Precision
.
org.apache.commons.math3.util.Precision.round(double x, int scale, int roundingMethod)
Вот краткая реализация, которая во много раз быстрее, чем использование BigDecimal или 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];
}
Удалите утверждения по вкусу.;)
Используйте эту простую функцию
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 ;
}
Я просто хочу добавить решение ubuntudroid. Я попробовал, и он не закруглялся, поэтому мне пришлось добавить
df.setRoundingMode(RoundingMode.FLOOR);
чтобы он работал.
Чтобы сделать это на 100% надежно, вам нужно передать аргумент как строку, а не как число с плавающей запятой. При указании в виде строки код легко писать. Причина этого в том, что
double x = 1.1;
не означает, что x будет фактически оценивать до 1.1, только до ближайшего точно представляемого числа.
Собственно, такую вещь легко написать:
public static double truncate(double value, int places) {
double multiplier = Math.pow(10, places);
return Math.floor(multiplier * value) / multiplier;
}
Обратите внимание, что это Math.floor, потому что Math.round не будет усекать.
О, и это возвращает double, потому что то, что большинство функций в классе Math возвращаются (например, Math.pow и Math.floor).
Предостережение: парные сосать для точности. Сначала нужно рассмотреть одно из решений BigDecimal.
Просто удалите дробную часть
public double trunk(double value){
return value - value % 1;
}
создал метод для этого.
public double roundDouble(double d, int places) {
return Math.round(d * Math.pow(10, (double) places)) / Math.pow(10, (double)places);
}