Pergunta

Eu tentei usar Formatter.format, mas que parece deixar a mantissa em números com 0 mantissa, enquanto que a versão C não. Existe um equivalente de g especificador de formato de C% em Java, e se não, há uma maneira de fingir? Minha intenção é preservar a mantissa exatamente como C de por razões de compatibilidade.

foo.c

#include <stdio.h>

int main (int argc, char const *argv[])
{
    printf("%g\n", 1.0);
    return 0;
}

Main.java

class Main {
        public static void main(String[] args) {
                System.out.printf("%g\n", 1.0);
        }
}

Console:

$ javac Main.java && java Main
1.00000
$ gcc foo.c && ./a.out
1

Da mesma forma, com 1,2 como entrada, a mantissa é maior na versão de Java

$ javac Main.java && java Main
1.20000
$ gcc foo.c && ./a.out
1.2
Foi útil?

Solução

Você já tentou o java.text.DecimalFormat classe ?

System.out.println(new DecimalFormat().format(1.0));

saídas:

1

Considerando o seguinte:

System.out.println(new DecimalFormat().format(1.2));

saídas:

1.2

Outras dicas

Editar : Este código faz com que a parte fracionária para ir em falta se o expoente é de 17 dígitos, por causa da minha incompreensão de como String.format formatado esses números. Então, não por favor não use este código: P

Obrigado pela contribuição, pessoal. Eu não poderia encontrar uma maneira de DecimalFormat configure ou NumberFormat exatamente clone a funcionalidade, mas parece que este método funciona (seguidos por exemplo):

String.format("%.17g", x).replaceFirst("\\.?0+(e|$)", "$1");

main.c

#include <stdio.h>

int main (int argc, char const *argv[])
{
    printf("%.*g\n", 17, -0.0);
    printf("%.*g\n", 17, 0.0);
    printf("%.*g\n", 17, 1.0);
    printf("%.*g\n", 17, 1.2);
    printf("%.*g\n", 17, 0.0000000123456789);
    printf("%.*g\n", 17, 1234567890000000.0);
    printf("%.*g\n", 17, 0.0000000123456789012345678);
    printf("%.*g\n", 17, 1234567890123456780000000.0);
    return 0;
}

Main.java

class Main {
        public static String formatDouble(double x) {
                return String.format("%.17g", x).replaceFirst("\\.?0+(e|$)", "$1");
        }

        public static void main(String[] args) {
                System.out.println(formatDouble(-0.0));
                System.out.println(formatDouble(0.0));
                System.out.println(formatDouble(1.0));
                System.out.println(formatDouble(1.2));
                System.out.println(formatDouble(0.0000000123456789));
                System.out.println(formatDouble(1234567890000000.0));
                System.out.println(formatDouble(0.0000000123456789012345678));
                System.out.println(formatDouble(1234567890123456780000000.0));
        }
}

e respectivas produções:

$ gcc foo.c && ./a.out
-0
0
1
1.2
1.23456789e-08
1234567890000000
1.2345678901234567e-08
1.2345678901234568e+24
$ javac Main.java && java Main
-0
0
1
1.2
1.23456789e-08
1234567890000000
1.2345678901234567e-08
1.2345678901234568e+24

Você pode usar um NumberFormat . Ao definir os dígitos de fração mínima a 0, mas deixando a máxima maior, ele deve fazer o que quiser.

Não é tão fácil como printf, mas deve funcionar.

Bem, você pode especificar quantos dígitos você quer: "% .2g" será exibido 1.2 como 1,20

Note que o uso

String.format("%.17g", x).replaceFirst("\\.?0+(e|$)", "$1")

falhar por 1.2345e-20 (tiras a zero a partir da extremidade, produzindo 1.2345e-2). Aqui está o que eu acabei usando no meu código:

String.format(Locale.US, "%.6g", x).replaceFirst("\\.0+(e|$)", "$1").replaceFirst("(\\.[0-9]*[1-9])(0+)(e|$)", "$1$3")

Basicamente, a expressão modificado para garantir que apenas zeros no final da parte fraccionada são removidos e dividir esta em dois casos. Mas obrigado por me apontar na direção certa.

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