Как напечатать двойное значение без научной нотации с помощью Java?
Я хочу напечатать двойное значение в Java без экспоненциальной формы.
double dexp = 12345678;
System.out.println("dexp: "+dexp);
он показывает это обозначение E:1.2345678E7.
Я хочу, чтобы он напечатал это так:12345678
каков наилучший способ предотвратить это?
12 ответов
вы могли бы использовать printf() С %f:
double dexp = 12345678;
System.out.printf("dexp: %f\n", dexp);
выводит dexp: 12345678.000000. Если вы не хотите дробную часть, используйте
System.out.printf("dexp: %.0f\n", dexp);
это использует язык спецификатора формата, объясненный в документация.
по умолчанию toString() формат, используемый в исходном коде, прописан здесь.
Java предотвращает обозначение E в двойном формате:
пять различных способов преобразования двойного в нормальное число:
import java.math.BigDecimal;
import java.text.DecimalFormat;
public class Runner {
    public static void main(String[] args) {
        double myvalue = 0.00000021d;
        //Option 1 Print bare double.
        System.out.println(myvalue);
        //Option2, use decimalFormat.
        DecimalFormat df = new DecimalFormat("#");
        df.setMaximumFractionDigits(8);
        System.out.println(df.format(myvalue));
        //Option 3, use printf.
        System.out.printf("%.9f", myvalue);
        System.out.println();
        //Option 4, convert toBigDecimal and ask for toPlainString().
        System.out.println(new BigDecimal(myvalue).toPlainString());
        System.out.println();
        //Option 5, String.format 
        System.out.println(String.format("%.12f", myvalue));
    }
}
эта программа печатает:
2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000
которые все одинаковое значение.
Protip: если вы путаете, почему эти случайные цифры появляются за определенным порогом в двойном значении, это видео объясняет: computerphile почему 0.1+0.2 равных 0.30000000000001?
короче:
если вы хотите избавиться от trailing zeros and Locale problems, то вам необходимо использовать:
double myValue = 0.00000021d;
DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340); // 340 = DecimalFormat.DOUBLE_FRACTION_DIGITS
System.out.println(df.format(myValue)); // Output: 0.00000021
объяснение:
почему другие ответы меня не устраивали:
- 
Double.toString()илиSystem.out.printlnилиFloatingDecimal.toJavaFormatStringиспользует научные обозначения, если double меньше 10^-3 или больше или равно 10^7
- 
С помощью %f, десятичная точность по умолчанию-6, в противном случае вы можете жестко закодировать его, но это приведет к добавлению дополнительных нулей, если у вас меньше десятичных знаков. Пример:double myValue = 0.00000021d; String.format("%.12f", myvalue); // Output: 0.000000210000
- 
С помощью setMaximumFractionDigits(0);или%.0fвы удаляете любую десятичную точность, которая подходит для целых чисел / лонгов, но не для double:double myValue = 0.00000021d; System.out.println(String.format("%.0f", myvalue)); // Output: 0 DecimalFormat df = new DecimalFormat("0"); System.out.println(df.format(myValue)); // Output: 0
- 
используя DecimalFormat, вы являетесь локальным зависимым. Во французском языке десятичный разделитель является запятой, а не точкой: double myValue = 0.00000021d; DecimalFormat df = new DecimalFormat("0"); df.setMaximumFractionDigits(340); System.out.println(df.format(myvalue)); // Output: 0,00000021использование английского языка гарантирует, что вы получите точка для десятичного разделителя, где будет работать ваша программа. 
почему через 340 потом setMaximumFractionDigits?
двум причинам:
- 
setMaximumFractionDigitsпринимает целое число, но его реализация имеет максимально допустимые цифрыDecimalFormat.DOUBLE_FRACTION_DIGITSчто равно 340
- 
Double.MIN_VALUE = 4.9E-324таким образом, с 340 цифрами вы уверены, что не округлить ваш двойной и потерять точность.
Вы можете попробовать его с DecimalFormat. С этим классом вы очень гибки в разборе ваших чисел.
Вы можете точно установить шаблон, который хотите использовать.
В вашем случае например:
double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678
у меня есть другое решение, включающее toPlainString () BigDecimal, но на этот раз с помощью строкового конструктора, который рекомендуется в javadoc:
этот конструктор совместим со значениями, возвращаемыми Float.toString и Double.метод toString. Обычно это предпочтительный способ преобразования float или double в BigDecimal, поскольку он не страдает от непредсказуемости конструктора BigDecimal(double).
это выглядит так в самая короткая форма:
return new BigDecimal(myDouble.toString()).stripTrailingZeros().toPlainString();
Pre Java 8, это приводит к " 0.0 " для любых нулевых двойников, поэтому вам нужно будет добавить:
if (myDouble.doubleValue() == 0)
    return "0";
NaN и бесконечные значения должны быть проверены дополнительно.
конечный результат всех этих соображений:
public static String doubleToString(Double d) {
    if (d == null)
        return null;
    if (d.isNaN() || d.isInfinite())
        return d.toString();
    // Pre Java 8, a value of 0 would yield "0.0" below
    if (d.doubleValue() == 0)
        return "0";
    return new BigDecimal(d.toString()).stripTrailingZeros().toPlainString();
}
Это также можно скопировать / вставить, чтобы хорошо работать с Float.
Это будет работать до тех пор, пока ваш номер является целым числом:
double dnexp = 12345678;
System.out.println("dexp: " + (long)dexp);
Если двойной переменной после запятой он будет обрезать его.
мне нужно было конвертировать некоторые двойные значения в валюту и обнаружил, что большинство решений были в порядке, но не для меня.
на DecimalFormat в конце концов, это был путь для меня, поэтому вот что я сделал:
   public String foo(double value) //Got here 6.743240136E7 or something..
    {
        DecimalFormat formatter;
        if(value - (int)value > 0.0)
            formatter = new DecimalFormat("0.00"); // Here you can also deal with rounding if you wish..
        else
            formatter = new DecimalFormat("0");
        return formatter.format(value);
    }
Как вы можете видеть, если число является естественным, я получаю-скажем-20000000 вместо 2E7 (и т. д.) - без запятой.
и если это decimal, я получаю только две десятичные цифры.
следующий код определяет, представлен ли указанный номер в научной нотации. Если это так, он представлен в обычном представлении с максимумом цифр "25".
 static String convertFromScientificNotation(double number) {
    // Check if in scientific notation
    if (String.valueOf(number).toLowerCase().contains("e")) {
        System.out.println("The scientific notation number'"
                + number
                + "' detected, it will be converted to normal representation with 25 maximum fraction digits.");
        NumberFormat formatter = new DecimalFormat();
        formatter.setMaximumFractionDigits(25);
        return formatter.format(number);
    } else
        return String.valueOf(number);
}
У меня была эта же проблема в моем коде, когда я использовал его в качестве строкового ввода в математике.Функция Eval (), которая принимает строку типа "x + 20 / 50"
Я просмотрел сотни статей... В конце концов, я пошел с этим из-за скорости. И потому что функция Eval собиралась преобразовать ее обратно в свой собственный формат чисел и математику.Eval() не поддерживал трейлинг E-07, который возвращали другие методы, и что-либо более 5 dp было слишком подробно для моего в любом случае, заявление.
теперь это используется в производственном коде для приложения с более чем 1000 пользователями...
double value = 0.0002111d;
String s = Double.toString(((int)(value * 100000.0d))/100000.0d); // Round to 5 dp
s display as:  0.00021
компилятор Java/Kotlin преобразует любое значение больше 9999999 (больше или равно 10 миллионам) в научную нотацию ie. Нотации эпсилион.
Ex: 12345678 преобразуется в 1.2345678E7
используйте этот код, чтобы избежать автоматического преобразования в научной нотации:
fun setTotalSalesValue(String total) {
        var valueWithoutEpsilon = total.toBigDecimal()
        /* Set the converted value to your android view using setText() function */
        totalSalesValue.setText() = valueWithoutEpsilon.toPlainString()
    }
Я думаю, что у всех была правильная идея, но все ответы не были простыми. Я вижу, что это очень полезный фрагмент кода. Вот фрагмент того, что будет работать:
System.out.println(String.format("%.8f", EnterYourDoubleVariableHere));
на ".8" установить количество десятичных знаков, которые вы хотели бы показать.
Я использую Eclipse, и это не сработало.
надеюсь, это было полезно. Я был бы признателен за любую обратную связь!
для целых значений, представленных double, вы можете использовать этот код, который намного быстрее, чем другие решения.
public static String doubleToString(final double d) {
    // check for integer, also see https://stackoverflow.com/a/9898613/868941 and
    // https://github.com/google/guava/blob/master/guava/src/com/google/common/math/DoubleMath.java
    if (isMathematicalInteger(d)) {
        return Long.toString((long)d);
    } else {
        // or use any of the solutions provided by others
        return Double.toString(d);
    }
}
// Java 8+
public static boolean isMathematicalInteger(final double d) {
    return StrictMath.rint(d) == d && Double.isFinite(d);
}
