How do I determine number of integer digits and the number of digits after decimal in a number like 234.12413
in Java.
Asked
Active
Viewed 1.2e+01k times
42
-
1possible dupe: http://stackoverflow.com/questions/5993124/problem-on-getting-digits-in-a-double-variable/5993212#5993212 – amit Jun 07 '11 at 11:42
-
For what possible feature of an application, would the program need to know that? Surely it is more a matter of displaying a `Double` or `Float` to show only a certain limit of precision. E.G. '12.158384' -> '12.16', '3.33333..' -> '3.33'. – Andrew Thompson Jun 07 '11 at 11:57
-
There are no decimal digits in a double. There are binary digits. – user207421 Sep 11 '15 at 21:32
-
Another way of looking at it: A double, at the hardware level on Intel platforms, is a 52-bit integer. And there is an 11-bit number that tells you where to put the decimal point. And one more bit for sign. – Vagrant Oct 14 '16 at 22:07
-
3Compared to casting String, I would like to recommend this. BigDecimal value = BigDecimal.valueOf(
); int decimalCount = Math.max(0, value .scale()); – elifekiz Jan 09 '19 at 13:22 -
You can convert to BigDecimal and do this: https://stackoverflow.com/questions/2296110/determine-number-of-decimal-place-using-bigdecimal – borjab Nov 19 '19 at 15:48
-
`new BigDecimal(String.valueOf(doubleNumber)).scale()`. Ref: baeldung.com/java-separate-double-into-integer-decimal-parts – Shanika Ediriweera Sep 03 '20 at 06:45
4 Answers
57
A double is not always an exact representation. You can only say how many decimal places you would have if you converted it to a String.
double d= 234.12413;
String text = Double.toString(Math.abs(d));
int integerPlaces = text.indexOf('.');
int decimalPlaces = text.length() - integerPlaces - 1;
This will only work for numbers which are not turned into exponent notation. You might consider 1.0 to have one or no decimal places.

Peter Lawrey
- 525,659
- 79
- 751
- 1,130
-
1
-
5This method will fail eventually, because the conversion `toString()` uses the decimal separator of the OS, not all OSs use dot `.` as decimal separator and you are using a literal dot, hence it will work only in some environments and under some circumstances. A better approach would be to use: `new DecimalFormat("#.#########").format(Math.abs(value)).replace(",",".")` to ensure your `text` variable always receive a literal dot. – Joe Almore Jan 30 '17 at 18:23
-
1Also it does not work for high numbers ending with zeros because 10000000 is represented as 1.0E7 etc. Therefore result[0] = 1 and result[1] = 3. `DecimalFormat` would help. The same problem have other solutions with `toString()` or `"" + doubleValue` – Fenix Feb 15 '17 at 16:31
-
3This is a decent answer, however it is not reliable because it does not work for any double. I was able to solve this answer using mathematics by looping through the powers of ten, and checking to see if `dbl * pow(10, i) % 1 == 0` was true. If that statement was true, then the number of decimal places is `i`. Adding an `if` at the beginning of the method to check if the double has no decimal: `if(dbl == (int)dbl) {return 0;}` completes the method. – Ian S. Jun 26 '17 at 21:46
-
@IanS. "it does not work for any double" Can you give an example as I did? – Peter Lawrey Jun 28 '17 at 14:47
-
4A counterexample to your solution would be, as Fenix said, 10,000,000. `Double.toString(10000000)` returns `1.0E7`. However, if you ran this number through my method, then `10000000.0D * Math.pow(10, 0) % 1 == 0` would be true, and the function would return 0. Unfortunately there are not enough characters per comment to fit the full implementation of the method. (I revised the method so there is no if-statement at the top anymore). – Ian S. Jun 29 '17 at 22:22
-
@IanS. I have this note already `This will only work for numbers which are not turned into exponent notation` Are there other examples? – Peter Lawrey Jun 30 '17 at 14:40
-
Not that I can find at the moment, but in my opinion, a mathematical solution is more reliable than an OS-dependent solution. I find that the mathematical solution was a good fit for what I was using it for at the time (double to `byte[]` conversion). The `Double.toString()` method is more practical for everyday use, however there are a few pitfall values that one must look out for. (P.S. you could add this to your method: `if(text.matches("[+-]?\\d+\\.\\d+E-\\d+")) return Integer.parseInt(text.substring(text.lastIndexOf('-')));` – Ian S. Jun 30 '17 at 17:00
-
@IanS. Java shouldn't be OS independent (it can be locale dependant) – Peter Lawrey Jul 01 '17 at 09:41
-
1@JoeAlmore You got that reversed. `toString()` will always use '.' ('\u002E') (explicitly mentioned in the [javadoc](https://docs.oracle.com/javase/8/docs/api/java/lang/Double.html#toString-double-)). It is `DecimalFormat` that will use a Locale-dependent decimal separator. – Andreas Dec 06 '18 at 16:53
-
@IanS Unfortunately, there are still edge cases that wouldn't work: `0.29d * 100d = 28.999999999999996`. So `0.29d * 100d % 1` should ideally be `0` but it's actually `0.9999999999999964` :/ – dcastro Jun 14 '19 at 09:32
-
-
1This would be a better approach. `new BigDecimal(String.valueOf(doubleNumber)).scale()`. Ref: baeldung.com/java-separate-double-into-integer-decimal-parts – Shanika Ediriweera Sep 03 '20 at 06:46
-
@ShanikaEdiriweera Can you say what makes this better? e.g. clarity, speed, accuracy, edge cases? – Peter Lawrey Sep 04 '20 at 07:45
-
1your solution won't work if the number is without decimal digits, will return 1 instead of 0 – MightGod Sep 22 '22 at 14:17
21
Double d = 234.12413;
String[] splitter = d.toString().split("\\.");
splitter[0].length(); // Before Decimal Count
splitter[1].length(); // After Decimal Count
10
String s = "" + 234.12413;
String[] result = s.split("\\.");
System.out.println(result[0].length() + " " + result[1].length());

Prince John Wesley
- 62,492
- 12
- 87
- 94
3
1) convert to string
2) substring from '.' to end
3) get the length of this substring

Gabriel Negut
- 13,860
- 4
- 38
- 45