Вопрос

У меня двойное значение = 1.068879335 Я хочу обойти его только с двумя десятичными значениями, такими как 1.07.

Я попробовал так

DecimalFormat df=new DecimalFormat("0.00");
String formate = df.format(value);
double finalValue = Double.parseDouble(formate) ;

Это дает мне это следующее исключение

java.lang.NumberFormatException: For input string: "1,07"
     at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224)
     at java.lang.Double.parseDouble(Double.java:510)

Может ли кто -нибудь сказать мне, что не так с моим кодом.

Конец мне нужен FinalValue = 1.07;

Это было полезно?

Решение

Обратите внимание на запятую в своей строке: "1,07". DecimalFormat использует специфичную для локали строку сепаратора, в то время как Double.parseDouble() не. Поскольку вы живете в стране, где десятичный сепаратор «», вы не можете проанализировать свой номер обратно.

Однако вы можете использовать то же самое DecimalFormat Чтобы проанализировать это обратно:

DecimalFormat df=new DecimalFormat("0.00");
String formate = df.format(value); 
double finalValue = (Double)df.parse(formate) ;

Но вместо этого вы действительно должны сделать это:

double finalValue = Math.round( value * 100.0 ) / 100.0;

Примечание: Как было указано, вы должны использовать плавающую запятую только в том случае, если вам не нужен точный контроль над точностью. (Финансовые расчеты являются основным примером, когда нет использовать их.)

Другие советы

Live @Sergey's Solution, но с целочисленным разделением.

double value = 23.8764367843;
double rounded = (double) Math.round(value * 100) / 100;
System.out.println(value +" rounded is "+ rounded);

отпечатки

23.8764367843 rounded is 23.88

РЕДАКТИРОВАТЬ: Как указывает Сергей, не должно быть никакой разницы между мультипливизированным двойным*int и double*Double и Diving Double/Int и Double/Double. Я не могу найти пример, где результат отличается. Однако на x86/x64 и других системах существует конкретная инструкция по машинному коду для смешанных двойных значений, которые, как я полагаю, используют JVM.

for (int j = 0; j < 11; j++) {
    long start = System.nanoTime();
    for (double i = 1; i < 1e6; i *= 1.0000001) {
        double rounded = (double) Math.round(i * 100) / 100;
    }
    long time = System.nanoTime() - start;
    System.out.printf("double,int operations %,d%n", time);
}
for (int j = 0; j < 11; j++) {
    long start = System.nanoTime();
    for (double i = 1; i < 1e6; i *= 1.0000001) {
        double rounded = (double) Math.round(i * 100.0) / 100.0;
    }
    long time = System.nanoTime() - start;
    System.out.printf("double,double operations %,d%n", time);
}

Отпечатки

double,int operations 613,552,212
double,int operations 661,823,569
double,int operations 659,398,960
double,int operations 659,343,506
double,int operations 653,851,816
double,int operations 645,317,212
double,int operations 647,765,219
double,int operations 655,101,137
double,int operations 657,407,715
double,int operations 654,858,858
double,int operations 648,702,279
double,double operations 1,178,561,102
double,double operations 1,187,694,386
double,double operations 1,184,338,024
double,double operations 1,178,556,353
double,double operations 1,176,622,937
double,double operations 1,169,324,313
double,double operations 1,173,162,162
double,double operations 1,169,027,348
double,double operations 1,175,080,353
double,double operations 1,182,830,988
double,double operations 1,185,028,544

Проблема заключается в том, что вы используете локализующееся форматер, который генерирует десятичную точку, специфичную для локали, то есть «в вашем случае». Но Double.parsedouble () ожидает нелокализованного двойного буквального. Вы можете решить свою проблему, используя метод анализа, специфичный для локализации, или изменив локаль вашего форматера на что-то, что использует ». как десятичная точка. Или даже лучше, избегайте ненужного форматирования, используя что -то вроде этого:

double rounded = (double) Math.round(value * 100.0) / 100.0;

Есть что -то в корне не так с тем, что вы пытаетесь сделать. Бинарные значения с плавающими точками не имеют Десятичные места. Вы не можете осмысленно вокруг одного до данного количества десятичных десятичных мест, потому что большинство «круглых» десятичных значений просто не могут быть представлены в виде бинарной фракции. Вот почему никогда не следует использовать float или же double представлять деньги.

Поэтому, если вы хотите десятичные места в вашем результате, этот результат должен быть либо String (что вы уже получили с DecimalFormat), или BigDecimal (который имеет setScale() Метод, который делает именно то, что вы хотите). В противном случае результат не может быть тем, кем вы хотите, чтобы он был.

Читать Руководство по плаванию Чтобы получить больше информации.

Попробуйте это: org.apache.commons.math3

Видеть:http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/precision.html

Apache Commons Mathematic Library Homepage:http://commons.apache.org/proper/commons-math/index.html

Внутренняя имплеметация этого метода:

public static double round(double x, int scale) {
    return round(x, scale, BigDecimal.ROUND_HALF_UP);
}

public static double round(double x, int scale, int roundingMethod) {
    try {
        return (new BigDecimal
               (Double.toString(x))
               .setScale(scale, roundingMethod))
               .doubleValue();
    } catch (NumberFormatException ex) {
        if (Double.isInfinite(x)) {
            return x;
        } else {
            return Double.NaN;
        }
    }
}

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

Пример, чтобы заставить вас понять, что я только что сказал.

double decimalnumber = 100.2397;
DecimalFormat dnf = new DecimalFormat( "#,###,###,##0.00" );
double roundednumber = new Double(dnf.format(decimalnumber)).doubleValue();

Это невозможно в запрошенном способе, потому что есть цифры с двумя десятичными местами, которые не могут быть выражены точно с использованием чисел с плавающей запятой IEEE (например, 1/10 = 0,1 не могут быть выражены как Double или же Float) Форматирование всегда должно происходить как последний шаг, прежде чем представить результат пользователю.

Я думаю, вы спрашиваете, потому что хотите иметь дело с денежными ценностями. Невозможно сделать это надежно с помощью чисел с плавающей точкой, вы подумаете о переходе на арифметику с фиксированной точкой. Это, вероятно, означает выполнение всех расчетов в «центах» вместо «долларов».

double TotalPrice=90.98989898898;

  DecimalFormat format_2Places = new DecimalFormat("0.00");

    TotalPrice = Double.valueOf(format_2Places.format(TotalPrice));

Вы можете использовать формат как здесь,

  public static double getDoubleValue(String value,int digit){
    if(value==null){
        value="0";
     }
    double i=0;
     try {
         DecimalFormat digitformat = new DecimalFormat("#.##");
         digitformat.setMaximumFractionDigits(digit);
        return Double.valueOf(digitformat.format(Double.parseDouble(value)));

    } catch (NumberFormatException numberFormatExp) {
        return i;   
    }
}

Если вы не хотите использовать DecimalFormat (например, из -за ее эффективности) и вам нужно общее решение, вы также можете попробовать этот метод, который использует масштабированное округление:

public static double roundToDigits(double value, int digitCount) {
    if (digitCount < 0)
        throw new IllegalArgumentException("Digit count must be positive for rounding!");

    double factor = Math.pow(10, digitCount);
    return (double)(Math.round(value * factor)) / factor;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top