Quero imprimir um valor duplo em Java sem forma exponencial.
double dexp = 12345678;
System.out.println("dexp: "+dexp);
Ele mostra esta notação E: 1.2345678E7
.
Quero que imprima assim: 12345678
Qual é a melhor maneira de evitar isso?
Quero imprimir um valor duplo em Java sem forma exponencial.
double dexp = 12345678;
System.out.println("dexp: "+dexp);
Ele mostra esta notação E: 1.2345678E7
.
Quero que imprima assim: 12345678
Qual é a melhor maneira de evitar isso?
Respostas:
Você poderia usar printf()
com %f
:
double dexp = 12345678;
System.out.printf("dexp: %f\n", dexp);
Isso será impresso dexp: 12345678.000000
. Se você não deseja a parte fracionária, use
System.out.printf("dexp: %.0f\n", dexp);
Isso usa a linguagem do especificador de formato explicada na documentação .
O toString()
formato padrão usado no seu código original está explicitado aqui .
%.0f
.
%.0f
arredonda o número. Existe uma maneira de simplesmente descartar os zeros à direita?
Cinco maneiras diferentes de converter um número duplo para um número normal:
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));
}
}
Este programa imprime:
2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000
Quais são todos do mesmo valor.
Protip: se você está confuso sobre o motivo pelo qual esses dígitos aleatórios aparecem além de um certo limite no valor duplo, este vídeo explica: computerphile por que 0.1
+0.2
igual a 0.30000000000001
?
Em resumo:
Se você quiser se livrar dos zeros à direita e dos problemas de localidade, use:
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
Explicação:
Por que outras respostas não me agradaram:
Double.toString()
ou System.out.println
ou FloatingDecimal.toJavaFormatString
usa notações científicas se o dobro for menor que 10 ^ -3 ou maior que ou igual a 10 ^ 7Ao usar %f
, a precisão decimal padrão é 6; caso contrário, você pode codificá-la, mas isso resultará em zeros extras adicionados se você tiver menos casas decimais. Exemplo:
double myValue = 0.00000021d;
String.format("%.12f", myvalue); // Output: 0.000000210000
Usando setMaximumFractionDigits(0);
ou %.0f
você remove qualquer precisão decimal, o que é bom para números inteiros / longos, mas não para o dobro:
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
Usando DecimalFormat, você depende localmente. Na localidade francesa, o separador decimal é uma vírgula, não um ponto:
double myValue = 0.00000021d;
DecimalFormat df = new DecimalFormat("0");
df.setMaximumFractionDigits(340);
System.out.println(df.format(myvalue)); // Output: 0,00000021
O uso do código do idioma PORTUGUÊS garante que você obtenha um ponto para o separador decimal, onde quer que o seu programa seja executado.
Por que usar 340 então para setMaximumFractionDigits
?
Duas razões:
setMaximumFractionDigits
aceita um número inteiro, mas sua implementação tem um número máximo permitido dos DecimalFormat.DOUBLE_FRACTION_DIGITS
quais é igual a 340Double.MIN_VALUE = 4.9E-324
portanto, com 340 dígitos, você não deve arredondar o dobro e perder a precisão.new BigDecimal(myvalue).toPlainString()
Da descrição em docs.oracle.com/javase/7/docs/api/java/math/… ), não é imediatamente óbvio como ele se comporta quando recebem diferentes tipos de números, mas elimina a notação científica .
new BigDecimal(0.00000021d).toPlainString()
saída 0.0000002100000000000000010850153241148685623329583904705941677093505859375
que não é o que você esperaria ...
BigDecimal.valueOf(0.00000021d).toPlainString()
funciona tão bem (ele usa o construtor String of BigDecimal é por isso)
Você pode experimentá-lo DecimalFormat
. Com esta classe, você é muito flexível ao analisar seus números.
Você pode definir exatamente o padrão que deseja usar.
No seu caso, por exemplo:
double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678
Eu tenho outra solução envolvendo o toPlainString () do BigDecimal, mas desta vez usando o construtor String, recomendado no javadoc:
esse construtor é compatível com os valores retornados por Float.toString e Double.toString. Geralmente, é a maneira preferida de converter um float ou duplicar em um BigDecimal, pois não sofre com a imprevisibilidade do construtor BigDecimal (double).
Parece assim em sua forma mais curta:
return new BigDecimal(myDouble.toString()).stripTrailingZeros().toPlainString();
Antes do Java 8, isso resulta em "0,0" para quaisquer duplas com valor zero, portanto, você deve adicionar:
if (myDouble.doubleValue() == 0)
return "0";
NaN e valores infinitos devem ser verificados extra.
O resultado final de todas estas considerações:
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();
}
Isso também pode ser copiado / colado para funcionar bem com o Float.
d.doubleValue() == 0
invés de d == 0
?
Eu precisava converter alguns valores duplos em moeda e descobri que a maioria das soluções estava correta, mas não para mim.
A DecimalFormat
acabou por ser o caminho para mim, então aqui está o que eu fiz:
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);
}
Como você pode ver, se o número for natural, recebo - digamos - 20000000 em vez de 2E7 (etc.) - sem nenhum ponto decimal.
E se for decimal, recebo apenas dois dígitos decimais.
O compilador Java / Kotlin converte qualquer valor maior que 9999999 (maior ou igual a 10 milhões) em notação científica, isto é. Notação Epsilion .
Ex: 12345678 é convertido em 1,2345678E7
Use este código para evitar a conversão automática em notação científica:
fun setTotalSalesValue(String total) {
var valueWithoutEpsilon = total.toBigDecimal()
/* Set the converted value to your android text view using setText() function */
salesTextView.setText( valueWithoutEpsilon.toPlainString() )
}
O código a seguir detecta se o número fornecido é apresentado em notação científica. Nesse caso, é representado na apresentação normal com um máximo de '25' dígitos.
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);
}
Acho que todos tiveram a ideia certa, mas todas as respostas não foram diretas. Eu posso ver isso sendo um pedaço de código muito útil. Aqui está um trecho do que irá funcionar:
System.out.println(String.format("%.8f", EnterYourDoubleVariableHere));
a ".8"
é onde você define o número de casas decimais que você gostaria de mostrar.
Estou usando o Eclipse e não funcionou.
Espero que isso tenha sido útil. Eu gostaria de receber qualquer feedback!
Eu tive esse mesmo problema no meu código de produção quando o estava usando como uma entrada de string para uma função math.Eval () que usa uma string como "x + 20/50"
Eu olhei para centenas de artigos ... No final, eu fui com isso por causa da velocidade. E porque a função Eval iria convertê-lo novamente em seu próprio formato numérico e math.Eval () não suportava o E-07 à direita que outros métodos retornavam, e qualquer coisa acima de 5 dp era muito detalhe para minha aplicação .
Agora isso é usado no código de produção para um aplicativo que possui mais de 1.000 usuários ...
double value = 0.0002111d;
String s = Double.toString(((int)(value * 100000.0d))/100000.0d); // Round to 5 dp
s display as: 0.00021
Isso pode ser uma tangente .... mas se você precisar colocar um valor numérico como um número inteiro (que é muito grande para ser um número inteiro) em um serializador (JSON etc.), provavelmente desejará "BigInterger"
Exemplo: o valor é uma sequência - 7515904334
Precisamos representá-lo como numérico em uma mensagem Json: {"contact_phone": "800220-3333", "servicer_id": 7515904334, "servicer_name": "SOME CORPORATION"}
Não podemos imprimi-lo ou obteremos o seguinte: {"contact_phone": "800220-3333", "servicer_id": "7515904334", "servicer_name": "SOME CORPORATION"}
Adicionar o valor ao nó dessa maneira produz o resultado desejado: BigInteger.valueOf (Long.parseLong (value, 10))
Não tenho certeza se isso é realmente um tópico, mas como essa pergunta foi a minha maior surpresa quando procurei minha solução, pensei em compartilhar aqui para o benefício de outras pessoas, mentir, que pesquisam mal. : D
Para valores inteiros representados por um double
, você pode usar esse código, que é muito mais rápido que as outras soluções.
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);
}
Minha solução: String str = String.format ("% .0f", yourDouble);
dexp: 12345681.000000
que é errado value.And, na verdade depois então eu quero para exibi-lo na minha página web onde se exibir como este1.2345678E7
.É lá de qualquer maneira pela qual eu posso armazená-lo em qualquer dupla como12345678
e alguma outra maneira?