9

我尝试使用 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;
}

主.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
4

6 回答 6

4

编辑:如果指数为 17 位,此代码会导致小数部分丢失,因为我误解了 String.format 如何格式化这些数字。所以请不要使用此代码:P

感谢您的输入,伙计们。我找不到配置 DecimalFormat 或 NumberFormat 以完全克隆功能的方法,但似乎这种方法有效(后面有一个示例):

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

主程序

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

主.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
于 2009-05-16T22:30:07.560 回答
2

您是否尝试过java.text.DecimalFormat类?

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

输出:

1

然而:

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

输出:

1.2
于 2009-05-16T21:08:26.057 回答
1

您可以使用NumberFormat。通过将最小小数位数设置为 0,但让最大值更大,它应该可以满足您的要求。

它不像 printf 那样简单,但它应该可以工作。

于 2009-05-16T21:07:50.240 回答
0

好吧,你可以指定你想要的位数:“%.2g”将 1.2 显示为 1.20

于 2009-05-16T21:04:56.550 回答
0

请注意,使用

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

基本上我修改了表达式以确保仅删除小数部分末尾的零并将其分为两种情况。但感谢您为我指明了正确的方向。

于 2017-06-29T13:19:15.173 回答
0

以上解决方案都不是完美的。在某些情况下,这里和那里有很多问题。所以我创建了一个小型库 Double2String 来解决这个特定问题:

https://github.com/coconut2015/double2string

于 2021-07-12T02:00:54.103 回答