Idiomatic way of counting digits


#1

In C-like languages counting digits in a number can be acomplished in 1 line like:

int num = 123456;
int length = 0;
for (int n = num; n != 0; n /= 10, length++);

But since such for loops are unavailable in Kotlin, how can I count them in 1-2 lines? And what’s the reason for excluding such for loops from language? Thank you.


#2
Math.floor(Math.log10(123456.0)).toInt() + 1

#3

The reason for excluding such loops from the language is that we know very few real-world tasks for which such a loop would be the most idiomatic way to solve the task.


#4

I wrote code that counts digits and/or does similar digit-by-digit operations on integers dozens of times in my life. I did not use C-style for loop for this. I always use while loop. It is just easier to write and to read – this is the key to the correct and maintainable code. In Kotlin I’d write it like this:

val num = 123456
var length = 0
var n = num
while (n != 0) {
    n /= 10
    length++
}

To summarize: putting multiple state-modification operations (n /= 10 and length++) onto the single line may seem cool, but it almost universally leads to harder-to-understand code.

There are few exception to the above rule, of course. There is a number of well-recognized patterns like someArray[i++] = value and similar ones where multiple modifications per line is actually good for better structure of the code. Beyond those patterns, it is a bad style.


#5

Thanks for the answer, now it makes sense.


#6

The unwary reader may recall that log is not defined for negative numbers, so don’t forget taking the absolute value if you write a function.

Furthermore, recall that log_b(a) = ln(a) / ln(b), which you can use to get the length of a in radix-b representation.