Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Improve performance on BigDecimal to double conversion

This is the Jdk7-b147 version of BigDecimal.doubleValue()

public double doubleValue(){
  if (scale == 0 && intCompact != INFLATED)
    return (double)intCompact;
  // Somewhat inefficient, but guaranteed to work.
  return Double.parseDouble(this.toString());
}

They admit that this way is inefficient! Is there a better/faster way than to use this method?

like image 448
durron597 Avatar asked Feb 06 '13 22:02

durron597


People also ask

Can BigDecimal be converted to double?

math. BigDecimal. doubleValue() is an in-built function which converts the BigDecimal object to a double. This function converts the BigDecimal to Double.

Should I use BigDecimal or double?

The main disadvantage is BigDecimal is slower than double. So if we have a system where low latency is crucial than the decimal part of a number, we should go for double. But in financial or any other systems where each digit of decimal part are important, BigDecimal should be chosen over double/float.

Why use BigDecimal instead of double in Java?

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 alltogether when summing as the difference in magnitude is so large. With BigDecimal this would not happen.

How accurate is BigDecimal?

This limits it to 15 to 17 decimal digits of accuracy. BigDecimal can grow to any size you need it to. Double operates in binary which means it can only precisely represent numbers which can be expressed as a finite number in binary. For example, 0.375 in binary is exactly 0.011.


1 Answers

There isn't a much better way to convert a BigDecimal to a double. This is because the algorithms to convert foo * 10^bar to baz * 2^quux efficiently, while keeping very specific rounding semantics, are extremely nasty and unpleasant -- see sun.misc.FloatingDecimal for details, or read this paper.

BigInteger.doubleValue(), on the other hand, does have lots of opportunities for optimization, since it needn't deal with decimal fractions, but only integers. I have a JDK patch pending that optimizes BigInteger.doubleValue() by slightly more than two orders of magnitude, though it's still awaiting review.

Update: The fix was added in OpenJDK 8, made available to the general public on March 18, 2014.

like image 91
Louis Wasserman Avatar answered Sep 18 '22 22:09

Louis Wasserman