обрезать двойное значение до 6 знаков после запятой

Я решал проблему, которая требует усечения вывода, и, к моему удивлению, я не смог найти способ урезать числа в java.

Вывод должен быть числом, за которым следует 6 знаков после запятой.

Я хочу, чтобы double truncate(double number,int places) и вывод был truncate(14/3.0) = 4.666666.

но то, что я получаю

public static double round(double value, int places) {
    if (places < 0) throw new IllegalArgumentException();

    long factor = (long) Math.pow(10, places);
    value = value * factor;
    long tmp = Math.round(value);
    return (double) tmp / factor;
  }
// rounds( 14/3.0 , 6 ) = 4.666667

С String.format я получаю

String.format("%.6f", 14/3.0) = 4.666667

Я также попробовал решение, которое я нашел в stackoverflow, в котором предлагалось использовать BigDecimal, и оно дало мне тот же ответ.

NumberFormat тоже похоже работает таким же образом

java.text.NumberFormat f = java.text.NumberFormat.getNumberInstance();
f.setMinimumFractionDigits(6);
System.out.println(f.format(14/3.0)); // 4.666667

Есть ли встроенный метод, который делает это, или мне нужно написать свой собственный, используя что-то вроде BigInteger? Я что-то делаю не так?


person nikhil    schedule 06.12.2012    source источник


Ответы (3)


Это потому, что вы не усекаете, а округляете:

long tmp = Math.round(value);

Если вместо этого вы используете бросок, он должен работать:

long tmp = (long) value;

Таким образом, приведенный ниже код выводит 4.666666, как вы и ожидали:

public static void main(String[] args) throws Exception {
    System.out.println(truncate(14/3.0, 6));
}

public static double truncate(double value, int places) {
    if (places < 0) {
        throw new IllegalArgumentException();
    }

    long factor = (long) Math.pow(10, places);
    value = value * factor;
    long tmp = (long) value;
    return (double) tmp / factor;
}
person assylias    schedule 06.12.2012
comment
Я хочу двойное значение, как помогает приведение к длинному? - person nikhil; 06.12.2012
comment
@nikhil в вашем методе round, замена, которую я предлагаю, превращает метод в метод truncate, который вы ищете. - person assylias; 06.12.2012
comment
Вы также можете использовать Math.floor. - person starblue; 07.12.2012
comment
@starblue Да, long factor = (long) Math.pow(10, places); return (double) Math.floor(value * factor) / factor; тоже работает. - person assylias; 07.12.2012

Двойники не имеют десятичных разрядов, поэтому вы не можете усечь их до какого-либо определенного числа. У них есть бинарные места. Если вам нужно конкретное десятичное представление, используйте DecimalFormat или BigDecimal..

person user207421    schedule 07.12.2012

Следующий фрагмент кода помог мне ограничить количество знаков после запятой (усечение) для двойного значения.

public static Double truncate (double valueToTruncate, int numberOfDecimalPlaces) {

if (valueToTruncate > 0) {
    return new BigDecimal(String.valueOf(valueToTruncate)).setScale(numberOfDecimalPlaces, BigDecimal.ROUND_FLOOR).doubleValue();
} else {
    return new BigDecimal(String.valueOf(valueToTruncate)).setScale(numberOfDecimalPlaces, BigDecimal.ROUND_CEILING).doubleValue();
}

}

Надеюсь, это поможет кому-то :)

person Madhu Tomy    schedule 24.04.2020