32

I'd like to allow the user to vary the precision of a String generated from a double. Right now, I'm trying something like

String foo = String.format("%.*f\n", precision, my_double);

However, I receive a java.util.UnknownFormatConversionException. My inspiration for this approach was C printf and this resource (section 1.3.1).

Do I have a simple syntax error somewhere, does Java support this case, or is there a better approach?

Edit:

I suppose I could do something like

String foo = String.format("%." + precision + "f\n", my_double);

but I'd still be interested in native support for such an operation.

Chai T. Rex
  • 2,972
  • 1
  • 15
  • 33
Willi Ballenthin
  • 6,444
  • 6
  • 38
  • 52
  • And in Kotlin your "something like" would be rather more elegant: val foo = "%.${precision}f".format(my_double) – Red wine Jan 19 '22 at 10:01

5 Answers5

19

You sort of answered your own question - build your format string dynamically... valid format strings follow the conventions outlined here: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html#syntax.

If you want a formatted decimal that occupies 8 total characters (including the decimal point) and you wanted 4 digits after the decimal point, your format string should look like "%8.4f"...

To my knowledge there is no "native support" in Java beyond format strings being flexible.

vicatcu
  • 5,407
  • 7
  • 41
  • 65
10

You can use the DecimalFormat class.

double d1 = 3.14159;
double d2 = 1.235;

DecimalFormat df = new DecimalFormat("#.##");

double roundedD1 = df.format(d); // 3.14
double roundedD2 = df.format(d); // 1.24

If you want to set the precision at run time call:

df.setMaximumFractionDigits(precision)
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
5

Why not :

String form = "%."+precision+"f\n";
String foo = String.format(form, my_double);

or :

public static String myFormat(String src, int precision, Object args...)
{
    String form = "%."+precision+"f\n";
    return String.format(form, args);
}
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
Gerdi
  • 53
  • 1
  • 4
  • 2
    So you suggest OP something he already knows and added in his question? – Tom Jun 30 '16 at 11:58
  • I'm mostly suggesting OP to make his own static function which will do what he wants (a native function of string format which includes variable precision). So yes and no, because he already has the tools to do it. Or at least that's what I'm trying to do. – Gerdi Jul 01 '16 at 20:04
1
double pi = Math.PI; // 3.141592653589793
int n = 5;
DecimalFormat df = new DecimalFormat();
df.setMaximumFractionDigits(n);
System.out.printf(df.format(pi)); // 3.14159

You can set value of n at runtime. Here from the above code given n = 5 will print 3.14159

0

Willi Mentzel solution updated for Java 17:

double d1 = 3.14159;
double d2 = 1.235;

DecimalFormat df = new DecimalFormat("#.##");

String roundedD1 = df.format(d); // 3.14
String roundedD2 = df.format(d); // 1.24
Lorenzo Lerate
  • 3,552
  • 3
  • 26
  • 25