Что является Java-эквивалентом спецификатора формата printf% g в C? - PullRequest
7 голосов
/ 17 мая 2009

Я пытался использовать Formatter.format, но, похоже, мантисса остается на числах с 0 мантиссой, в то время как версия C этого не делает. Есть ли в Java эквивалент спецификатора формата% g в Java, и если нет, есть ли способ его подделать? Мое намерение состоит в том, чтобы сохранить мантиссу точно так же, как С, из соображений совместимости.

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);
        }
}

Консоль

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

Аналогичным образом, с вводом 1.2 мантисса длиннее в версии Java

$ javac Main.java && java Main
1.20000
$ gcc foo.c && ./a.out
1.2

Ответы [ 5 ]

4 голосов
/ 17 мая 2009

редактировать : Этот код приводит к тому, что дробная часть пропадает, если показатель степени составляет 17 цифр, из-за моего неправильного понимания того, как String.format форматировал эти числа. Поэтому не используйте этот код: P

Спасибо за вклад, ребята. Я не смог найти способ настроить DecimalFormat или NumberFormat для точного клонирования функциональности, но кажется, что этот метод работает (сопровождается примером):

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));
        }
}

и их выходы:

$ 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
2 голосов
/ 17 мая 2009

Вы пробовали класс java.text.DecimalFormat ?

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

выходов:

1

тогда:

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

выходы:

1.2
1 голос
/ 17 мая 2009

Вы можете использовать NumberFormat . Установив минимальные цифры дроби на 0, но оставив максимум больше, он должен делать то, что вы хотите.

Это не так просто, как printf, но должно работать.

0 голосов
/ 29 июня 2017

Обратите внимание, что с помощью

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

терпит неудачу для 1.2345e-20 (удаляет ноль с конца, производя 1.2345e-2). Вот что я использовал в своем коде:

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

По сути, я изменил выражение, чтобы обеспечить удаление только нулей в конце дробной части, и разделил это на два случая. Но спасибо, что указал мне правильное направление.

0 голосов
/ 17 мая 2009

хорошо, вы можете указать, сколько цифр вы хотите: "% .2g" будет отображать 1,2 как 1,20

...