An explanation of how the above algorithm works:

Start with the identity log10(x) =
(y + log10(x) - y) =
(y + log10(x) - log10(10y)) =
(y + log10(x * 10-y)) =
(y + ((1 / 10) * log10((x * 10-y) 10)))

The first step in calculating log10(x) is to calculate floor(log10(x)). This is quite easily accomplished by counting the number of divisions by 10 necessary to get a value from 1 to 10 [excluding 10]. This is a useful value for y.

The number you get after dividing x by 10 y times is (x * 10-y). You see where this is going.

The purpose of step 1 is to get y and (x * 10-y). The purpose of step 2 is to get (x * 10-y)10. The purpose of the recursion is to calculate log10((x * 10-y)10). The purpose of writing the value as a string of digits and concatenating the single-digit results of the second and subsequent y values is to perform the addition and incorporate the (1 / 10) factor.

If the value to start with were less than 1, the easiest way to adapt this algorithm would be to calculate the log of the reciprocal (multiplicative inverse) of the value, then invert the sign of the result.