Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we need to convert the double into a string, before we can convert it into a BigDecimal?

Tags:

java

math

The source for round in apache commons looks like this:

public static double round(double x, int scale, int roundingMethod) {
    try {
        return (new java.math.BigDecimal(Double.toString(x)).setScale(scale, roundingMethod)).doubleValue();
    } catch (NumberFormatException ex) {
        if (Double.isInfinite(x)) {
            return x;
        } else {
            return Double.NaN;
        }
    }
}

I was wondering, when creating the BigDecimal why did they chose to convert the double to a string (using the Double.toString) instead of simply using the double itself?

In other words, what's wrong with this? :

public static double round(double x, int scale, int roundingMethod) {
    try {
        return (new java.math.BigDecimal(x).setScale(scale, roundingMethod)).doubleValue();
    } catch (NumberFormatException ex) {
        if (Double.isInfinite(x)) {
            return x;
        } else {
            return Double.NaN;
        }
    }
}
like image 459
Pacerier Avatar asked Nov 10 '11 01:11

Pacerier


People also ask

Why use BigDecimal instead of double?

BigDecimal reduces the chances of calculation errors. On double numbers, the BigDecimal class provides arithmetic, scale management, rounding, comparison, format conversion, and hashing functions. It compensates for the time complexity by handling large and small floating-point integers with exceptional precision.

What is difference between BigDecimal and double?

A BigDecimal is an exact way of representing numbers. A Double has a certain precision. Working with doubles of various magnitudes (say d1=1000.0 and d2=0.001 ) could result in the 0.001 being dropped altogether when summing as the difference in magnitude is so large. With BigDecimal this would not happen.

Can we convert string to BigDecimal in Java?

We can convert a String into BigDecimal in Java using one of the below methods: BigDecimal(String) constructor. BigDecimal. valueOf() method.


1 Answers

It's because the result of BigDecimal(double) constructor is unpredictable as mentioned in javadoc.

One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625

The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one.

Test Case:

System.out.println(java.math.BigDecimal.valueOf(0.1).toString());
System.out.println(new java.math.BigDecimal(0.1).toString());
like image 131
Fabian Barney Avatar answered Oct 11 '22 07:10

Fabian Barney