Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the Java equivalent of C's printf %g format specifier?

I tried using Formatter.format, but that seems to leave the mantissa on numbers with 0 mantissa, whereas the C version does not. Is there an equivalent of C's %g format specifier in Java, and if not, is there a way to fake it? My intention is to preserve the mantissa exactly like C's for compatibility reasons.

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

Console:

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

Similarly, with 1.2 as input, the mantissa is longer in Java's version

$ javac Main.java && java Main
1.20000
$ gcc foo.c && ./a.out
1.2
like image 604
John Douthat Avatar asked May 16 '09 20:05

John Douthat


People also ask

What is %N in Java printf?

The %d specifies that the single variable is a decimal integer. The %n is a platform-independent newline character. The output is: The value of i is: 461012. The printf and format methods are overloaded.

What is format specifier in Java?

Format specifiers include flags, width, precision, and conversion characters in this sequence: %[flags][width][.precision]conversion-character. Specifiers in the brackets are optional. Internally, printf() uses the java. util. Formatter class to parse the format string and generate the output.

What is printf in Java?

The printf method in Java can be used to output a formatted string to the console using various format specifiers. It is also an overloaded method of the PrintStream class. The printf method behaves the same as the invocation of the format() method.

What does %s mean in Java?

the %s is a 'format character', indicating "insert a string here". The extra parameters after the string in your two function calls are the values to fill into the format character placeholders: In the first example, %s will be replaced with the contents of the command variable.


2 Answers

edit: This code causes the fractional part to go missing if the exponent is 17 digits, because of my misunderstanding of how String.format formatted those numbers. So don't please don't use this code :P

Thanks for the input, guys. I couldn't find a way to configure DecimalFormat or NumberFormat to exactly clone the functionality, but it seems this method works (followed by an example):

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

and their outputs:

$ 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
like image 84
John Douthat Avatar answered Sep 19 '22 17:09

John Douthat


Have you tried the java.text.DecimalFormat class?

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

outputs:

1

whereas:

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

outputs:

1.2
like image 39
highlycaffeinated Avatar answered Sep 21 '22 17:09

highlycaffeinated