Java: How to Set Precision for Double Value

Java: How to set Precision for double value?

You can't set the precision of a double (or Double) to a specified number of decimal digits, because floating-point values don't have decimal digits. They have binary digits.

You will have to convert into a decimal radix, either via BigDecimal or DecimalFormat, depending on what you want to do with the value later.

See also my answer to this question for a refutation of the inevitable *100/100 answers.

Double value with specific precision in java

DecimalFormat will allow you to define how many digits you want to display. A '0' will force an output of digits even if the value is zero, whereas a '#' will omit zeros.

System.out.print(new DecimalFormat("#0.0000").format(value)+" kg\n"); should to the trick.

See the documentation

Note: if used frequently, for performance reasons you should instantiate the formatter only once and store the reference: final DecimalFormat df = new DecimalFormat("#0.0000");. Then use df.format(value).

Retain precision with double in Java

As others have mentioned, you'll probably want to use the BigDecimal class, if you want to have an exact representation of 11.4.

Now, a little explanation into why this is happening:

The float and double primitive types in Java are floating point numbers, where the number is stored as a binary representation of a fraction and a exponent.

More specifically, a double-precision floating point value such as the double type is a 64-bit value, where:

  • 1 bit denotes the sign (positive or negative).
  • 11 bits for the exponent.
  • 52 bits for the significant digits (the fractional part as a binary).

These parts are combined to produce a double representation of a value.

(Source: Wikipedia: Double precision)

For a detailed description of how floating point values are handled in Java, see the Section 4.2.3: Floating-Point Types, Formats, and Values of the Java Language Specification.

The byte, char, int, long types are fixed-point numbers, which are exact representions of numbers. Unlike fixed point numbers, floating point numbers will some times (safe to assume "most of the time") not be able to return an exact representation of a number. This is the reason why you end up with 11.399999999999 as the result of 5.6 + 5.8.

When requiring a value that is exact, such as 1.5 or 150.1005, you'll want to use one of the fixed-point types, which will be able to represent the number exactly.

As has been mentioned several times already, Java has a BigDecimal class which will handle very large numbers and very small numbers.

From the Java API Reference for the BigDecimal class:

Immutable,
arbitrary-precision signed decimal
numbers. A BigDecimal consists of an
arbitrary precision integer unscaled
value and a 32-bit integer scale. If
zero or positive, the scale is the
number of digits to the right of the
decimal point. If negative, the
unscaled value of the number is
multiplied by ten to the power of the
negation of the scale. The value of
the number represented by the
BigDecimal is therefore (unscaledValue
× 10^-scale).

There has been many questions on Stack Overflow relating to the matter of floating point numbers and its precision. Here is a list of related questions that may be of interest:

  • Why do I see a double variable initialized to some value like 21.4 as 21.399999618530273?
  • How to print really big numbers in C++
  • How is floating point stored? When does it matter?
  • Use Float or Decimal for Accounting Application Dollar Amount?

If you really want to get down to the nitty gritty details of floating point numbers, take a look at What Every Computer Scientist Should Know About Floating-Point Arithmetic.

defining decimal places of a double number in Java

Simply do this,

double doubleValue=4.1;

String.format(Locale.ROOT, "%.2f", doubleValue );

Output:

4.10

Using this approach you don't need to make use of DecimalFormat which will also reduce unnecessary imports

How to round a number to n decimal places in Java

Use setRoundingMode, set the RoundingMode explicitly to handle your issue with the half-even round, then use the format pattern for your required output.

Example:

DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {
Double d = n.doubleValue();
System.out.println(df.format(d));
}

gives the output:

12
123.1235
0.23
0.1
2341234.2125

EDIT: The original answer does not address the accuracy of the double values. That is fine if you don't care much whether it rounds up or down. But if you want accurate rounding, then you need to take the expected accuracy of the values into account. Floating point values have a binary representation internally. That means that a value like 2.7735 does not actually have that exact value internally. It can be slightly larger or slightly smaller. If the internal value is slightly smaller, then it will not round up to 2.7740. To remedy that situation, you need to be aware of the accuracy of the values that you are working with, and add or subtract that value before rounding. For example, when you know that your values are accurate up to 6 digits, then to round half-way values up, add that accuracy to the value:

Double d = n.doubleValue() + 1e-6;

To round down, subtract the accuracy.

How to set precision of double values to be of the form ##.## at ALL times?

You can use:

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

How to print a float with 2 decimal places in Java?

You can use the printf method, like so:

System.out.printf("%.2f", val);

In short, the %.2f syntax tells Java to return your variable (val) with 2 decimal places (.2) in decimal representation of a floating-point number (f) from the start of the format specifier (%).

There are other conversion characters you can use besides f:

  • d: decimal integer
  • o: octal integer
  • e: floating-point in scientific notation

Round a double to 2 decimal places

Here's an utility that rounds (instead of truncating) a double to specified number of decimal places.

For example:

round(200.3456, 2); // returns 200.35

Original version; watch out with this

public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();

long factor = (long) Math.pow(10, places);
value = value * factor;
long tmp = Math.round(value);
return (double) tmp / factor;
}

This breaks down badly in corner cases with either a very high number of decimal places (e.g. round(1000.0d, 17)) or large integer part (e.g. round(90080070060.1d, 9)). Thanks to Sloin for pointing this out.

I've been using the above to round "not-too-big" doubles to 2 or 3 decimal places happily for years (for example to clean up time in seconds for logging purposes: 27.987654321987 -> 27.99). But I guess it's best to avoid it, since more reliable ways are readily available, with cleaner code too.

So, use this instead

(Adapted from this answer by Louis Wasserman and this one by Sean Owen.)

public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();

BigDecimal bd = BigDecimal.valueOf(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}

Note that HALF_UP is the rounding mode "commonly taught at school". Peruse the RoundingMode documentation, if you suspect you need something else such as Bankers’ Rounding.

Of course, if you prefer, you can inline the above into a one-liner:

new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()

And in every case

Always remember that floating point representations using float and double are inexact.
For example, consider these expressions:

999199.1231231235 == 999199.1231231236 // true
1.03 - 0.41 // 0.6200000000000001

For exactness, you want to use BigDecimal. And while at it, use the constructor that takes a String, never the one taking double. For instance, try executing this:

System.out.println(new BigDecimal(1.03).subtract(new BigDecimal(0.41)));
System.out.println(new BigDecimal("1.03").subtract(new BigDecimal("0.41")));

Some excellent further reading on the topic:

  • Item 48: "Avoid float and double if exact answers are required" in Effective Java (2nd ed) by Joshua Bloch
  • What Every Programmer Should Know About Floating-Point Arithmetic

If you wanted String formatting instead of (or in addition to) strictly rounding numbers, see the other answers.

Specifically, note that round(200, 0) returns 200.0. If you want to output "200.00", you should first round and then format the result for output (which is perfectly explained in Jesper's answer).

Convert double to BigDecimal and set BigDecimal Precision

It prints 47.48000 if you use another MathContext:

BigDecimal b = new BigDecimal(d, MathContext.DECIMAL64);

Just pick the context you need.

Java double - Only zeros after certain decimal place

tl;dr

  • Eliminate any use of floating-point types double/Double and float/Float if you want accurate results with a wide range/precision.
  • Use only BigDecimal objects.

Use only BigDecimal, without double

The moment you involve a double primitive value or a Double object, you loose accuracy due to floating-point math.

Your method takes a double as its first argument named num. If you want accuracy and range/precision, take a BigDecimal instead.

static String solve( BigDecimal num, int decimalPlaces ) { … }

Call that method in this manner. Notice we pass the twelve as a string literal rather than as a numeric literal.

String result = Whatever.solve ( new BigDecimal( "12" ) , 80 ) ;

You cannot use comparator syntax with objects, such as <=. Your line while(Math.pow((currentNumber.add(toAdd).doubleValue()), 2) <= num) should instead call the method BigDecimal::pow.

Minor issue… Your line System.out.print( currentNumber.toPlainString() should be System.out.println( …, calling println rather than print.

This might be close to the code you seek. I am no math whiz so I cannot vouch for the logic.

static String solve ( BigDecimal num , int decimalPlaces )
{
BigDecimal toAdd = new BigDecimal( "1.0" );
BigDecimal currentNumber = new BigDecimal( "0.0" );

for ( int i = 0 ; i <= decimalPlaces ; i++ )
{
currentNumber = currentNumber.setScale( i );

System.out.println( currentNumber.toPlainString() + " >> " + i + "\r" );
while ( currentNumber.add( toAdd ).pow( 2 ).compareTo( num ) <= 0 )
{
currentNumber = currentNumber.add( toAdd );
}

toAdd = toAdd.divide( BigDecimal.TEN );
}

return currentNumber.toPlainString();
}

See this code run live on IdeOne.com.

0          >> 0
3.0 >> 1
3.40 >> 2
3.460 >> 3
3.4640 >> 4
3.46410 >> 5
3.464100 >> 6
3.4641010 >> 7
3.46410160 >> 8
3.464101610 >> 9
3.4641016150 >> 10
3.46410161510 >> 11
3.464101615130 >> 12
3.4641016151370 >> 13
3.46410161513770 >> 14
3.464101615137750 >> 15
3.4641016151377540 >> 16
3.46410161513775450 >> 17
3.464101615137754580 >> 18
3.4641016151377545870 >> 19
3.46410161513775458700 >> 20
3.464101615137754587050 >> 21
3.4641016151377545870540 >> 22
3.46410161513775458705480 >> 23
3.464101615137754587054890 >> 24
3.4641016151377545870548920 >> 25
3.46410161513775458705489260 >> 26
3.464101615137754587054892680 >> 27
3.4641016151377545870548926830 >> 28
3.46410161513775458705489268300 >> 29
3.464101615137754587054892683010 >> 30
3.4641016151377545870548926830110 >> 31
3.46410161513775458705489268301170 >> 32
3.464101615137754587054892683011740 >> 33
3.4641016151377545870548926830117440 >> 34
3.46410161513775458705489268301174470 >> 35
3.464101615137754587054892683011744730 >> 36
3.4641016151377545870548926830117447330 >> 37
3.46410161513775458705489268301174473380 >> 38
3.464101615137754587054892683011744733880 >> 39
3.4641016151377545870548926830117447338850 >> 40
3.46410161513775458705489268301174473388560 >> 41
3.464101615137754587054892683011744733885610 >> 42
3.4641016151377545870548926830117447338856100 >> 43
3.46410161513775458705489268301174473388561050 >> 44
3.464101615137754587054892683011744733885610500 >> 45
3.4641016151377545870548926830117447338856105070 >> 46
3.46410161513775458705489268301174473388561050760 >> 47
3.464101615137754587054892683011744733885610507620 >> 48
3.4641016151377545870548926830117447338856105076200 >> 49
3.46410161513775458705489268301174473388561050762070 >> 50
3.464101615137754587054892683011744733885610507620760 >> 51
3.4641016151377545870548926830117447338856105076207610 >> 52
3.46410161513775458705489268301174473388561050762076120 >> 53
3.464101615137754587054892683011744733885610507620761250 >> 54
3.4641016151377545870548926830117447338856105076207612560 >> 55
3.46410161513775458705489268301174473388561050762076125610 >> 56
3.464101615137754587054892683011744733885610507620761256110 >> 57
3.4641016151377545870548926830117447338856105076207612561110 >> 58
3.46410161513775458705489268301174473388561050762076125611160 >> 59
3.464101615137754587054892683011744733885610507620761256111610 >> 60
3.4641016151377545870548926830117447338856105076207612561116130 >> 61
3.46410161513775458705489268301174473388561050762076125611161390 >> 62
3.464101615137754587054892683011744733885610507620761256111613950 >> 63
3.4641016151377545870548926830117447338856105076207612561116139580 >> 64
3.46410161513775458705489268301174473388561050762076125611161395890 >> 65
3.464101615137754587054892683011744733885610507620761256111613958900 >> 66
3.4641016151377545870548926830117447338856105076207612561116139589030 >> 67
3.46410161513775458705489268301174473388561050762076125611161395890380 >> 68
3.464101615137754587054892683011744733885610507620761256111613958903860 >> 69
3.4641016151377545870548926830117447338856105076207612561116139589038660 >> 70
3.46410161513775458705489268301174473388561050762076125611161395890386600 >> 71
3.464101615137754587054892683011744733885610507620761256111613958903866030 >> 72
3.4641016151377545870548926830117447338856105076207612561116139589038660330 >> 73
3.46410161513775458705489268301174473388561050762076125611161395890386603380 >> 74
3.464101615137754587054892683011744733885610507620761256111613958903866033810 >> 75
3.4641016151377545870548926830117447338856105076207612561116139589038660338170 >> 76
3.46410161513775458705489268301174473388561050762076125611161395890386603381760 >> 77
3.464101615137754587054892683011744733885610507620761256111613958903866033817600 >> 78
3.4641016151377545870548926830117447338856105076207612561116139589038660338176000 >> 79
3.46410161513775458705489268301174473388561050762076125611161395890386603381760000 >> 80
result: 3.46410161513775458705489268301174473388561050762076125611161395890386603381760007


Related Topics



Leave a reply



Submit