12

How do I round a double to 5 decimal places, without using DecimalFormat?

bharath
  • 14,283
  • 16
  • 57
  • 95
Kevin Boyd
  • 12,121
  • 28
  • 86
  • 128
  • 1
    Why would you want to avoid the class that exists exactly for this job? And if you want the result to be a double, you're basically asking for something impossible. You simply cannot round a *binary* double to a given number of *decimal* places, except in a few special cases. – Michael Borgwardt Apr 19 '10 at 21:04
  • 5
    @ Michael: No DecimalFormat in JavaME – Kevin Boyd Apr 30 '11 at 11:16

8 Answers8

15

You can round to the fifth decimal place by making it the first decimal place by multiplying your number. Then do normal rounding, and make it the fifth decimal place again.

Let's say the value to round is a double named x:

double factor = 1e5; // = 1 * 10^5 = 100000.
double result = Math.round(x * factor) / factor;

If you want to round to 6 decimal places, let factor be 1e6, and so on.

Joren
  • 14,472
  • 3
  • 50
  • 54
  • 3
    -1: can't believe this got voted up that much, as this isn't really rounding at all. See Jon's answer for why. – Michael Borgwardt Apr 19 '10 at 21:05
  • I don't see the problem. It was asked how to round a `double` to five decimal places, and this is the best you're going to get. Obviously you should not actually use a `double` if you're representing decimal values, but that wasn't the question. – Joren Apr 20 '10 at 01:19
  • 1
    Note: While it **may** limits the digits to 5 digits, it cannot be certain to be correct, as it has no means of ensuring that the integer value `Math.round(x * factor)` can be represented in `factor`-ths, or that it will be limited to the exponent value of places (i.e. 5 places of the fractional portion). For more info [Java theory and practice: Where's your point? (Rounding Errors)](http://www.ibm.com/developerworks/java/library/j-jtp0114/#N101BC) and [What Every Scientist Should Know About Floating-Point Arithmetic](http://www.math.umd.edu/~jkolesar/mait613/floating_point_math.pdf) – mctylr Aug 18 '11 at 21:40
  • @mctylr: You're right about the correctness of course, but as I've said before, this is the best way you're going to get with `double`. If you want exact decimal calculations, you shouldn't be using `double`. Binary floating point calculations are used for things like scientific computations where all your values are inherently inexact, and in that situation some approximate rounding to 5 decimal places, for example for display purposes, is *perfectly fine* – Joren Aug 21 '11 at 19:01
  • 4
    `Math.round()` is not available in J2ME. – Nate Jan 25 '13 at 10:19
11

Whatever you do, if you end up with a double value it's unlikely to be exactly 5 decimal places. That just isn't the way binary floating point arithmetic works. The best you'll do is "the double value closest to the original value rounded to 5 decimal places". If you were to print out the exact value of that double, it would still probably have more than 5 decimal places.

If you really want exact decimal values, you should use BigDecimal.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 5
    Whatever you do, you can not use `BigDecimal` in Java ME - since there's no such thing - neither in [CLDC](http://en.wikipedia.org/wiki/Connected_Limited_Device_Configuration) nor in [CDC](http://en.wikipedia.org/wiki/Connected_Device_Configuration) profiles – gnat Sep 22 '11 at 17:10
8

Multiply by 100000. Add 0.5. Truncate to integer. Then divide by 100000.

Code:

double original = 17.77777777;
int factor = 100000;
int scaled_and_rounded = (int)(original * factor + 0.5);
double rounded = (double)scaled_and_rounded / factor;
Thomas Padron-McCarthy
  • 27,232
  • 8
  • 51
  • 75
3

If you are okay with external libraries, you can have a look at microfloat, specifically MicroDouble.toString(double d, int length).

Zed
  • 57,028
  • 9
  • 76
  • 100
2

Try the following

double value = Double.valueOf(String.format(Locale.US, "%1$.5f", 5.565858845));

System.out.println(value); // prints 5.56586

value = Double.valueOf(String.format(Locale.US, "%1$.5f", 5.56585258));

System.out.println(value); // prints 5.56585

Or if you want minimal amount of code

Use import static

import static java.lang.Double.valueOf;
import static java.util.Locale.US;
import static java.lang.String.format;

And

double value = valueOf(format(US, "%1$.5f", 5.56585258));

regards,

Arthur Ronald
  • 33,349
  • 20
  • 110
  • 136
2
DecimalFormat roundFormatter = new DecimalFormat("########0.00000");

public Double round(Double d)
    {
        return Double.parseDouble(roundFormatter.format(d));
    }
Milhous
  • 14,473
  • 16
  • 63
  • 82
1
public static double roundNumber(double num, int dec) {
        return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
}
Niger
  • 3,916
  • 5
  • 30
  • 30
0

I stumbled upon here looking for a way to limit my double number to two decimal places, so not truncating nor rounding it. Math.Truncate gives you the integral part of the double number and discards everything after the decimal point, so 10.123456 becomes 10 after truncation. Math.Round rounds the number to the nearest integral value so 10.65 becomes 11 while 10.45 becomes 10. So both of these functions did not meet my needs (I wish that .Net had overloaded both of these to allow truncating or rounding up to a certain number of decimal places). The easiest way to do what I needed is:

//First create a random number 
Random rand = new Random();

//Then make it a double by getting the NextDouble (this gives you a value 
//between 0 and 1 so I add 10 to make it a number between 10 and 11
double chn = 10 + rand.NextDouble();

//Now convert this number to string fixed to two decimal places by using the
//Format "F2" in ToString
string strChannel = chn.ToString("F2");

//See the string in Output window
System.Diagnostics.Debug.WriteLine("Channel Added: " + strChannel);

//Now convert the string back to double so you have the double (chn) 
//restricted to two decimal places
chn = double.Parse(strChannel);
wildriver
  • 21
  • 4