1

I have two double variables:

double a = 1.109
double b = 5.0E-5;

But b is changable and I want to achieve fixed numbers of decimal places depending of b number, for example above I want achieve this result:

Result = 1.10900

But not only print, I need to send it to other method and my double must have fixed numbers of decimal places like in example.

CeZet
  • 1,473
  • 5
  • 22
  • 44

4 Answers4

3

It sounds like you want arbitrary precision on the actual value (as opposed to just output). double doesn't give you that. BigDecimal does though. Its BigDecimal(String) constructor sets the value and the scale (number of places to the right of the decimal) from a string, so:

BigDecimal d = new BigDecimal("1.10900");

BigDecimal then gives you various math operations to stay within that scale, with various rounding options.

If at some point you need to get the double value of the BigDecimal, you can use its doubleValue method. But note that at that point, again, you don't have a fixed number of places to the right of the decimal anymore.

Here's an example contrasting BigDecimal and double (Live Copy):

import java.math.*;

class Example
{
    public static void main (String[] args) throws java.lang.Exception
    {
        BigDecimal bd = new BigDecimal("1.10900");
        bd = bd.divide(new BigDecimal("27"), BigDecimal.ROUND_HALF_DOWN);
        System.out.println("1.109 / 27 using BigDecimal to five places: " + bd);

        double d = 1.109;
        d = d / 27.0;
        System.out.println("1.109 / 27 using double:                    " + d);
    }
}

Output:

1.109 / 27 using BigDecimal to five places: 0.04107
1.109 / 27 using double:                    0.041074074074074075
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I need double values, maybe do this with `BIgDecimal` and next write to double ? – CeZet Feb 22 '16 at 08:34
  • @Czarq92: You can get a `double` from a `BigDecimal` via its `doubleValue()` method. – T.J. Crowder Feb 22 '16 at 08:36
  • Hmm... But how made fixed numbers of value `a` by `b` ? – CeZet Feb 22 '16 at 08:37
  • @Czarq92: I note your comment to Tim saying "...and send it to others with right fixed number of decimal places." You can give them a `double`, or you can give them something with a fixed number of decimal places, but you can't do both. – T.J. Crowder Feb 22 '16 at 08:37
  • So I cant convert and send to other method (`public void SendToLabel(double value`) the `double` value with decimal places precision ? – CeZet Feb 22 '16 at 08:41
  • 2
    @Czarq92: No, that's just not something `double` provides. – T.J. Crowder Feb 22 '16 at 08:42
  • In conclusion: `double` values CANT looks like `1.10900` because it cut last `00` and return `1.109`, right ? – CeZet Feb 22 '16 at 08:45
  • 2
    @Czarq92: Well, `double` doesn't remove the `00`, it's just not there. `1.10900` is numerically identical to `1.109`. `double`s store *floating point numbers*, without any concept of "places to the right of the decimal." You can add that when formatting them to a string, but that's only formatting. `BigDecimal` does have the concept of "places to the right of the decimal", built in. – T.J. Crowder Feb 22 '16 at 08:48
  • @Czarq92 No, you need to view it from a different perspective. A double is a certain number what takes up 64 bits in memory. When a double is printed, by default, it is printed like, for example, `1.109`, but its real contents are just zeros and ones. So everytime you need to print it *in another format than the default formatting*, then you must use `NumberFormat` or `BigDecimal`. – MC Emperor Feb 22 '16 at 08:49
  • It doesn't solve my problem but You helped to understand why I can't achieve this, thanks ! :D – CeZet Feb 22 '16 at 08:54
1

Try using a number formatter:

NumberFormat formatter = new DecimalFormat("#0.00000");     
double a = 1.109;
double b = 5.0E-5;
System.out.println(a);
System.out.println(b);

Output:

1.10900
0.00005
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • This way only print it for me but I must convert it and send to others method with right fixed number of decimal places. – CeZet Feb 22 '16 at 08:36
  • I'm not sure your use case will be practical in production. How can you set the precision for your entire program based on a value which may not yet have occurred? Typically, for scientific applications you would have an internal (and external) fixed precision for your customers. – Tim Biegeleisen Feb 22 '16 at 08:39
0

A simple solution is to round the result as needed. This is not only faster than using BigDecimal it can be less error prone as Java doesn't have language support for BigDecimal making it harder to write/read and validate. A simple method for rounding half up for 5 decimal spaces is

public static double round5(double d) {
    final double factor = 1e5;
    return d > Long.MAX_VALUE / factor || d < -Long.MAX_VALUE / factor ? d :
            (long) (d < 0 ? d * factor - 0.5 : d * factor + 0.5) / factor;
}

Note: when you print the double you will still need to specify the number of decimal places you need e.g.

System.out.printf("%.5f", value);
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
-1

Use java printf-like routine (note it produces platform dependent decimal separators):

String.format("%.5f", a)
Vasily Liaskovsky
  • 2,248
  • 1
  • 17
  • 32