Как напечатать двойное значение без научной нотации с использованием Java?
Я хочу напечатать двойное значение в Java без экспоненциальной формы.
double dexp = 12345678;
System.out.println("dexp: "+dexp);
Он показывает это обозначение E: 1.2345678E7
.
Я хочу, чтобы он печатал это следующим образом: 12345678
Каков наилучший способ предотвратить это?
Ответы
Ответ 1
Вы можете использовать printf()
с %f
:
double dexp = 12345678;
System.out.printf("dexp: %f\n", dexp);
Откроется dexp: 12345678.000000
. Если вы не хотите дробную часть, используйте
System.out.printf("dexp: %.0f\n", dexp);
Это использует язык спецификатора формата, указанный в документации.
Формат toString()
по умолчанию, используемый в вашем исходном коде, указан здесь.
Ответ 2
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.print(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
Которые имеют все одинаковое значение.
Подсказка: если вы не уверены, почему эти случайные цифры появляются за определенным пороговым значением в двойном значении, это видео объясняет: computerphile, почему 0.1
+ 0.2
равно 0.30000000000001
?
http://youtube.com/watch?v=PZRI1IfStY0
Ответ 3
Короче:
Если вы хотите избавиться от конечных нулей и проблем локали, вы должны использовать:
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
Использование языкового стандарта ENGLISH гарантирует, что вы получите точку для разделителя с разделителями, где бы ваша программа не запускалась.
Зачем использовать 340 для setMaximumFractionDigits
?
Две причины:
-
setMaximumFractionDigits
принимает целое число, но его реализация имеет максимальные значения, допустимые для DecimalFormat.DOUBLE_FRACTION_DIGITS
, что равно 340
-
Double.MIN_VALUE = 4.9E-324
, поэтому с 340 цифрами вы уверены, что не будете округлять свой двойник и не теряете точность.
Ответ 4
Вы можете попробовать его с помощью DecimalFormat
. С помощью этого класса вы очень гибко разбираете свои номера.
Вы можете точно установить шаблон, который хотите использовать.
Например, в вашем случае:
double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678
Ответ 5
У меня есть другое решение с участием BigDecimal toPlainString(), но на этот раз с помощью String-constructor, который рекомендуется в 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.
Ответ 6
Это будет работать до тех пор, пока ваш номер будет целым числом:
double dnexp = 12345678;
System.out.println("dexp: " + (long)dexp);
Если двойная переменная имеет точность после десятичной точки, она усекает ее.
Ответ 7
Мне нужно было преобразовать несколько значений double в валюту и обнаружил, что большинство решений были в порядке, но не для меня.
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 (и т.д.) - без какой-либо десятичной точки.
И если он десятичный, я получаю только две десятичные цифры.
Ответ 8
Следующий код определяет, представлен ли предоставленный номер в научной нотации. Если это так, то оно представлено в нормальном представлении с максимальным числом "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);
}
Ответ 9
Компилятор Java/Kotlin преобразует любое значение больше 9999999 (больше или равно 10 миллионам) в научную нотацию, т.е. Epsilion обозначение.
Например: 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()
}
Ответ 10
У меня была такая же проблема в моем производственном коде, когда я использовал его как строковый ввод в функцию math.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
Ответ 11
Я думаю, что у всех была правильная идея, но все ответы были непростыми.
Я вижу, что это очень полезный фрагмент кода. Вот фрагмент того, что будет работать:
System.out.println(String.format("%.8f", EnterYourDoubleVariableHere));
the ".8"
- это то, где вы указываете количество десятичных знаков, которые вы хотели бы показать.
Я использую Eclipse, и это не сработало.
Надеюсь, это было полезно. Буду признателен за любую обратную связь!
Ответ 12
Для целочисленных значений, представленных 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);
}