什么是C的printf%g格式说明符的Java等价物?

时间:2009-05-16 20:57:26

标签: java c printf formatter

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

6 个答案:

答案 0 :(得分:4)

修改: 如果指数为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

答案 1 :(得分:2)

您是否尝试过java.text.DecimalFormat课程?

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

输出:

1

,而:

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

输出:

1.2

答案 2 :(得分:1)

您可以使用NumberFormat。通过将最小分数设置为0,但保留最大值,它应该做你想要的。

它不像printf那么容易,但它应该可以工作。

答案 3 :(得分:0)

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

答案 4 :(得分: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")

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

答案 5 :(得分:0)

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

https://github.com/coconut2015/double2string