Pergunta

Em Java, estou tentando obter o DecimalFormat para aplicar o sinal em um sinal de expoente. Quando é positivo, preciso de um sinal de mais para aparecer. Pelo que li, isso parece um acéfalo, mas, para mim, sempre levanta um erro. Aprecio que possa haver outros métodos para atingir meu objetivo, mas gostaria de entender por que, nesse método específico, o erro está ocorrendo.

Double result = 123.456;
String sresult;

//This works
NumberFormat formatter = new DecimalFormat("0.00000E00");
        sresult = formatter.format(result); 
        System.out.println(sresult);        //1.23456E02

//This doesn't work
formatter = new DecimalFormat("0.00000E+00"); //Want to enforce the sign to appear
        sresult = formatter.format(result); 
        System.out.println(sresult);        //Expected 1.23456E+02 but error occurs

O erro que é lançado:

Exception in thread "main" java.lang.IllegalArgumentException:
Malformed exponential pattern "0.00000E+00"
    at java.text.DecimalFormat.applyPattern(Unknown Source)
    at java.text.DecimalFormat.(Unknown Source)
    at deccheck.main(deccheck.java:13)

Agradeço qualquer insight. Obrigado, Mark

Foi útil?

Solução

Jeito fácil:

formatter = new DecimalFormat("0.00000E00"); // Want to enforce the sign to appear
sresult = formatter.format(result);
if (!sresult.contains("E-")) { //don't blast a negative sign
    sresult = sresult.replace("E", "E+");
}
System.out.println(sresult);

Saídas 1.23456E+02 para o seu exemplo.

Mas não acredito que haja uma maneira de fazer isso de dentro do DecimalFormat padronizar. Ou pelo menos o javadoc não indica que existe um.

Editar: Trashgod traz um bom ponto. Você provavelmente gostaria de obter sinais positivos e negativos de DecimalFormatSymbols Se você planeja localizar isso em diferentes regiões.

Editar 2: Andrei apontou que E também é uma variável de localização. Mostra o que eu sei sobre localização.

Outras dicas

Eu gostaria de estender a solução por J Flemm. O "E" e "-" não são constantes, eles podem ser definidos como Decimalformatsymbols. Portanto, as substituições devem respeitar isso:

public static String hoola(final String s, final DecimalFormatSymbols symbols) {
    String result;
    final String expo = symbols.getExponentSeparator();
    final char minus = symbols.getMinusSign();
    if (!s.contains(expo + minus)) { // don't blast a negative sign
    result = s.replace(expo, expo + '+');
    } else {result=s;}
    return result;
}

/**
 * @param args
 */
public static void main(final String[] args) {
    final DecimalFormat decForm = (DecimalFormat) NumberFormat
            .getInstance(Locale.GERMAN);
    final DecimalFormatSymbols newSymbols = new DecimalFormatSymbols(
            Locale.GERMAN);
    newSymbols.setExponentSeparator("*10^");
    newSymbols.setMinusSign('\u2212');
    decForm.setDecimalFormatSymbols(newSymbols);
    decForm.applyPattern("0.00000E00");
    System.out.println(hoola(decForm.format(1234.567), decForm
            .getDecimalFormatSymbols()));
    System.out.println(hoola(decForm.format(000.00567), decForm
            .getDecimalFormatSymbols()));
}

O resultado é:

  • 1,23457*10^+03
  • 5,67000*10^−03

Eu não acho que o personagem '+' seja um personagem aceito em um padrão (depois de estudar os javadocs). E o padrão para a parte exponencial SI descrita como:

 Exponent:
         E MinimumExponent
 MinimumExponent:
         0 MinimumExponent(opt)

Se você adicionar alguma coisa lá, ele confundirá o analisador. Eu acho que sua única opção é dar o padrão normal (sem '+') e, em seguida, obter a string e usar o Regex para adicionar o '+' lá.

sresult = formatter.format(result);
sresult = sresult.replaceAll("E([^\\-]+)", "E+$1");

A melhor opção pode ser estender o decimalformato e fazer isso no método de formato substituído

A abordagem de @J Flemm é atraente porque "expoentes negativos são formatados usando o sinal menos localizado, não o prefixo e o sufixo do padrão" - - -DecimalFormat.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top