No, there is no built-in function that I know about.
There is a simple way to do this, though. Double.toString will give you a string containing ALL significant decimal digits in the double. The following are some properties of that string:
- The String that results may be in decimal notation or scientific
notation, depending on the value of the double.
- Doubles that convert to decimals 10,000,000 or larger or smaller than
1/1000 result in scientific notation. Otherwise, they are in decimal
notation.
Using Double.toString to figure out how many decimal places there are essentially comprises how many significant digits to the right of the decimal point minus a scientific notation exponent, if there is one. Decimal notation will always have at least one digit to the right of the decimal point, and at least one digit to the left of the decimal point, even if it is a zero. Since we are concerned about decimal places for significant digits, a trailing zero to the right of the decimal point is a concern and should not be counted as a decimal place.
The following code will make a good calculation for you:
StringBuffer stringBuffer = new StringBuffer(Double.toString(1234.567890D));
System.out.println(stringBuffer.toString());
int i; // general purpose character index
int exponent;
int decimalPlaces;
if ((i = stringBuffer.indexOf("E")) > -1) { // scientific notation...
// turn scientific notation exponent into an integer
exponent = Integer.parseInt(stringBuffer.substring(i + 1));
// truncate the exponent from the StringBuffer
stringBuffer = stringBuffer.delete(i, stringBuffer.length());
} else { // decimal notation, could be trailing zero
exponent = 0; // no exponent, so zero
// point i to trailing zero and truncate it, if there is one
if (stringBuffer.charAt((i = stringBuffer.length() - 1)) == '0') {
stringBuffer = stringBuffer.deleteCharAt(i); // delete trailing zero
}
}
// stringBuffer now contains only significant digits to the
// right of the decimal point, if there are any
decimalPlaces = stringBuffer.length() - 1 - stringBuffer.indexOf(".") - exponent;
// zero or positive number is decimal places
// negative number is number of zeroes to the left of the decimal point
// between the decimal point and the least significant digit
System.out.println(decimalPlaces);
I have some questions about the question posed. What kind of precision is expected with the decimal representation of a double? Are doubles being used to inappropriately perform decimal computations? Decimal computations with decimal fractions using floats and doubles can have results that unexpectedly have 16 or 17 significant digits and may be only approximations of the expected results from equivalent decimal computations.
One aspect of float, doubles, long doubles (aka quads) that seems to stymie programmers and designers is that all these formats are actually stored as binary fractional numbers that can only approximate decimal numbers except for a very, very few numbers, most of which are fairly close to the values 1, -1, plus the value zero. As one progresses towards positive infinity or zero from 1, or towards negative infinity or zero from -1, the sparseness of the approximation will become apparent.
Almost all decimal fractions have no direct representation in floats and doubles. Only decimal fractions that can be comprised from the sum of some combination of the following series of fractions have an exact representation:
1, 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128, 1/256, ..., 1/4503599627370496
All the rest are approximations.
Integers greater than +9007199254740992 or less than -9007199254740992 may not have an exact representation and the sparseness increases exponentially as integers increase above the positive or decrease below the negative values, respectively.
Another way to look at this is to realize that IEEE 64-bit doubles, normalized, approximate positive and negative decimal numbers having absolute values ranging from 2.225073858507201400 E -308 through 1.797693134862315700 E +308. However, there are only 1.8446744073709551616 E +19 values available for these approximations. That means about 1.0 E +607 decimal values share a representation with some other decimal values that are more closely approximated by a double.
The behavior of floats and doubles wrecks havoc with decimal computations requiring exact decimal accuracy, such as financial calculations and is why, unless a high-precision approximation is acceptable, one should use scaled integers and longs, or classes such as BigInteger and BigDecimal, for computations requiring exact decimal accuracy, rounding and precision.