Что такое Java-эквивалент спецификатора формата printf %g в C?

StackOverflow https://stackoverflow.com/questions/873298

  •  22-08-2019
  •  | 
  •  

Вопрос

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

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
Это было полезно?

Решение

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

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

выходы:

1

тогда как:

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

выходы:

1.2

Другие советы

редактировать:Этот код приводит к исчезновению дробной части, если показатель степени равен 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

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

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

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

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

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")

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top