Topics › Basics › Know Basic Maths
Count all Digits of a Number
Java source ↗ Edit this article ↗
Jump to code:
Problem
You are given an integer n. Return the number of decimal digits in n. The minus sign of a negative number is not a digit, and 0 is written with one digit, so it has one.
Constraints: n fits in a 32-bit signed integer, so -2^31 ≤ n ≤ 2^31 - 1 and the answer is always between 1 and 10.
Example 1
n = 12345
answer = 5 // the digits are 1, 2, 3, 4, 5
Example 2
n = -987
answer = 3 // the sign is ignored, the digits are 9, 8, 7
Example 3
n = 0
answer = 1 // zero is written as a single digit
This looks trivial, and it is, but the loop at the heart of it, “peel off the last digit with % 10, drop it with / 10”, is the same loop that drives reversing a number, checking a palindrome, summing digits and testing Armstrong numbers. It is worth doing once very carefully.
Approach 1: Brute force, via a string
Intuition. The decimal representation of a number is exactly the string you get from Long.toString. Count its characters. We convert to long first and take the absolute value so the sign never appears in the string.
Algorithm.
- Compute
abs = |n|as along. - Convert
absto its decimal string. - Return the string’s length.
static int bruteForce(int n) {
long abs = Math.abs((long) n);
return Long.toString(abs).length();
}
Complexity. Time O(d) where d is the digit count, because building the string touches every digit. Space O(d) for the string.
It works, and it is the fastest thing to type in an interview as a sanity check, but it allocates a String to answer a numeric question. The interviewer is really asking whether you know how to walk the digits of a number.
Approach 2: Better, divide by 10 until nothing is left
Intuition. Integer division by 10 removes the last decimal digit: 12345 / 10 = 1234. Every division drops exactly one digit, so the number of divisions needed to reach 0 is the number of digits. The single special case is n = 0, which is already 0 before any division and would otherwise be counted as having zero digits.
Algorithm.
- Let
x = |n|as along. Ifx == 0, return1. - Set
count = 0. - While
x > 0: dox /= 10andcount++. - Return
count.
static int better(int n) {
long x = Math.abs((long) n);
if (x == 0) return 1;
int count = 0;
while (x > 0) {
x /= 10;
count++;
}
return count;
}
Dry run on n = 12345:
| iteration | x before | x after / 10 |
count |
|---|---|---|---|
| 1 | 12345 | 1234 | 1 |
| 2 | 1234 | 123 | 2 |
| 3 | 123 | 12 | 3 |
| 4 | 12 | 1 | 4 |
| 5 | 1 | 0 | 5 |
The loop stops because x is 0, and count = 5.
Complexity. Time O(d), one division per digit, which is O(log10 n). Space O(1).
This is the approach to remember: no allocation, and it generalises to every digit-manipulation problem (replace the count++ with whatever you want to do with x % 10).
Approach 3: Optimal, a logarithm
Intuition. A positive integer x has d digits exactly when 10^(d-1) ≤ x < 10^d. Taking log10 of that inequality gives d - 1 ≤ log10(x) < d, so d = floor(log10(x)) + 1. That is a constant-time formula.
Two details matter. First, log10(0) is -infinity, so 0 must be handled before the formula. Second, floating-point logarithms are approximate in general; Java’s Math.log10 is specified to return exactly k when the argument is exactly 10^k, which is precisely the boundary case we care about, so the formula is safe for every int.
Algorithm.
- Let
x = |n|as along. Ifx == 0, return1. - Return
floor(log10(x)) + 1.
static int optimal(int n) {
long x = Math.abs((long) n);
if (x == 0) return 1;
return (int) Math.floor(Math.log10(x)) + 1;
}
Complexity. Time O(1), a single floating-point operation. Space O(1).
In practice the “better” loop runs at most ten times for an int, so the difference between O(d) and O(1) is invisible. Use the logarithm when you need the digit count of many huge numbers (or as a one-liner), and use the loop when you are about to do something with each digit anyway.
Edge cases and pitfalls
- Zero. Both the division loop and the logarithm would report
0digits forn = 0. Return1explicitly. The string approach gets this right for free because"0"has length 1. - Negative numbers. Take the absolute value first, or the
%//loop would produce negative remainders andLong.toStringwould include the-. Math.abs(Integer.MIN_VALUE)is still negative.-2^31has no positive counterpart inint, soMath.abson theintreturns-2^31unchanged and the loop never runs. Cast tolongbefore taking the absolute value, as every method above does. The tests includeInteger.MIN_VALUE, which has 10 digits.- Exact powers of ten.
1000has 4 digits. A logarithm computed with a tiny downward error would give2.9999...and the wrong answer; Java guaranteesMath.log10(1000) == 3.0, but in other languages you should add a small epsilon or stick to the loop. - Off-by-one in the loop condition.
while (x > 0)is correct for positivex.while (x > 9)plus a finalcount + 1also works and avoids the zero special case, but is easier to get wrong. - A related variant. Some sheets phrase the problem as “count the digits of
nthat evenly dividen” (forn = 1012, the digits1,1and2divide1012, so the answer is3; a digit0must be skipped to avoid division by zero). The same% 10loop solves it: replacecount++withif (digit != 0 && n % digit == 0) count++.
Related problems
- Reverse a number uses the same digit loop but rebuilds the number backwards.
- Palindrome Number compares a number with its digit-reversal.
- Check if the Number is Armstrong needs the digit count first, then raises each digit to that power.
- Print all Divisors and Check for Prime Number are the next basic-maths loops in the sheet.