代码之家  ›  专栏  ›  技术社区  ›  John Douthat

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

  •  7
  • John Douthat  · 技术社区  · 15 年前

    我尝试使用formatter.format,但这似乎会将尾数留在尾数为0的数字上,而C版则没有。在Java中是否有等价于C的%G格式说明符,如果没有,有没有办法伪造它呢?出于兼容性的原因,我的目的是保持尾数与C完全相同。

    Fo.C

    #include <stdio.h>
    
    int main (int argc, char const *argv[])
    {
        printf("%g\n", 1.0);
        return 0;
    }
    

    主类

    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 回复  |  直到 15 年前
        1
  •  2
  •   highlycaffeinated    15 年前

    你试过了吗 java.text.DecimalFormat 班级?

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

    输出:

    1
    

    鉴于:

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

    输出:

    1.2
    
        2
  •  4
  •   John Douthat    13 年前

    编辑 : 如果指数是17位,这段代码会导致小数部分丢失,因为我对string.format如何格式化这些数字有误解。所以请不要使用这个代码:p

    谢谢你们的意见,伙计们。我找不到一种方法来配置decimalformat或numberformat以精确克隆功能,但似乎此方法有效(后面是一个示例):

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

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

    主类

    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
    
        3
  •  1
  •   MBCook    15 年前

    你可以使用 NumberFormat .通过将最小小数位数设置为0,但保留较大的最大小数位数,它应该按照您的需要进行操作。

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

        4
  •  0
  •   Matey    15 年前

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

        5
  •  0
  •   Guðbjörn Freyr Jónsson    7 年前

    注意使用

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

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