The Pathological Programmer Returns: How NOT to write your own log function

I had a particularly perverse and evil thought today while dealing with strings in C#.

A string is a first-class object in C#. This means we can do things like

char[] foo = "This is my string, which is an object".ToCharArray();

In true object oriented fashion, we can string properties together as well. So let’s say I have a string. I can take the length of it, turn that number into a string, and take the length of that number. Turns out that the number we wind up with is an extremely rough approximation of the base 10 logarithm of the length of our original string. Knowing this, we can conclude that it is time to rock as we make our own highly inefficient, and mostly inaccurate function to determine the base 10 log of a number.

        public static int CalculateLog(int num)
        {
            string numStr = \"\";
            for (int i = 1; i < = num; i++)
            {
                numStr = numStr + \"!\";
            }
            return numStr.ToCharArray().Length.ToString().ToCharArray().Length - 1;
        }
 

So, there you have it. A slow, inefficient algorithm to give you the base 10 log of a number with less than 1 digit of precision (since we’re going to be wrong more than half of the time because our algorithm just drops the decimal part of the logarithm. That sound you just heard? That’s the sound of all of the engineers reading this blog’s heads exploding.)

On my computer it takes a minute and 14 seconds (and 87 hundredths of a second) to evaluate CalculateLog(100000), and it comes up with an answer of 5. It takes nearly the same amount of time to evaluate CalculateLog(99999), and it comes up with an answer of 4. Please don’t use this function for designing airplanes, at least, not any airplanes I’m going to be flying in. (Or airplanes which might fly over my house, for that matter.)

When analyzing this function to figure out why it takes so long, it helps to know that strings in C# are immutable, that is to say, they never ever change. So when we do numStr = numStr + "!";, what we’re really doing is creating an entirely new string, with an entirely new chunk of memory. (The old string will get garbage collected, eventually.) In other words, we’re consuming space in (roughly) the order of O(n^2).

Leave a Reply