algorithmmathtime-complexitylogarithmcoding-efficiency

Does taking logrithm in a program taxes the computer?


No of digits can be calculated by a loop as well as taking log10. So which one is more efficient? Taking log is just one line statement but what happens internally can be more costly that a simple loop. In another case which is more efficient an n^2 algo with log or an n^2 algo without log using some more space complexity?

In more general sense , I want to ask that is taking log same as simple arithmetic operators that we do like (int a + int b) or the computer has to go some rigorous procedure within?


Solution

  • This answer is only dealing with non-negative numbers, but it should be easy to make it work for negative numbers too. It also assumes 64 bit numbers are used.

    I would never use log10 to calculate the number of digits. Because of the following reasons:

    If you want a one-liner, I would go with the simple: ("" + number).length()

    You could repeatedly divide the number by 10 to get the result, but @YvesDaoust pointed out that multiplication is much faster.

    Here would be a simple implementation:

    // Java implementation, the highest long is about 9.2e18, so 19 digits
    public int countDigits(long number) {
        if (number >= 1000000000000000000L) // otherwise n would overflow
            return 19;
        int count = 1;
        for (long n = 10;; n *= 10) {
            if (number < n)
                return count;
            count++;
        }
    }
    

    But if the expected numbers are evenly distributed, then we would have to check the most digits first and go backwards. This is because there are 10 numbers with 1 digit, 90 numbers with 2 digits, 900 with 3, 9000 with 4 and so on.

    We can also precalculate the numbers. This would give something like this:

    private static final long[] digitCount = new long[18];
    static {
        digitCount[0] = 10;
        for (int i = 1; i < 18; i++) {
            digitCount[i] = digitCount[i - 1] * 10;
        }
    }
    
    public int countDigits(long number) {
        for (int i = 17; i >= 0; i--) {
            if (number >= digitCount[i])
                return i + 2;
        }
        return 1;
    }