Digit Counting

There are many situations in which a program needs to know the number of digits in an int. Unfortunately, int variables don’t have properties other than their value. In other words, anthropomorphizing a little, int variables don’t know anything about themselves. This chapter considers solutions to this problem given this observation.

Motivation

As you know from Chapter 4 on digit manipulation, in order to drop or extract digits from the left side of an integer, you needed to know the number of digits in the number. In the examples in that chapter, the number of digits was known. Unfortunately, that isn’t always the case. For example, credit card account numbers might have between six and nine digits. The problem, then, is that of determining the number of digits in a number.

Review

As you also know from Chapter 4 on digit manipulation, the position of a digit corresponds to a particular power of 10. Specifically, the digit in position \(n\) (counting from the right, starting with 0) corresponds to the \(10^n\)s place. For example, position \(2\) corresponds to the \(10^2\) or \(100\)s place. To count digits you need to be able to invert the process. For example, to count a three-digit number, you need to find the position that the \(100\)s place corresponds to.

As you hopefully recall, this is the domain of the logarithm. In a decimal (i.e., base 10) representation, the \(\log\_{10}(x)\) is often described as the value of \(n\) that \(10\) must be raised to in order to get \(x\). More formally, \(\log\_{10}(x)\) is the value of \(n\) that satisfies \(x = 10^n\). So, returning to our example, the position of the \(100\)s place corresponds to \(\log\_{10}(100)\), which is \(2\) (since \(10^2\) is \(100\)). More generally, \(\log\_{b}(x)\) is the value of \(n\) that satisfies \(x = b^n\), where \(b\) is referred to as the base (or radix) of the logarithm.

Thinking About The Problem

Evaluating \(\log\_{10}(x)\) can be quite difficult, in general. However, it is easy to find bounds. For example, since \(\log\_{10}(100)\) is \(2\) and \(\log\_{10}(1000)\) is \(3\) (and logarithms are monotonic) it follows that \(\log\_{10}(x)\) is in the interval \(\[2, 3)\) for any \(x \in \[100, 1000)\). This means that the \(\log\_{10}\) of any three-digit number is in \(\[2, 3)\) and that the \(\log\_{10}\) of any four-digit number is in \(\[3, 4)\). For example:

  • Math.log10(7198) evaluates to approximately 3.8572118423168926 which, as expected, is in the interval \(\[3, 4)\).
  • Math.log10(462) evaluates to approximately 2.6646419755561257 which, as expected, is in the interval \(\[2, 3)\).
  • Math.log10(10000) evaluates to 5.0 which, as expected, is in the interval \(\[5, 6)\).

The Pattern

More generally, the \(\log\_{10}\) of any \(n\)-digit number will be in the interval \(\[n-1, n)\), which means it will be greater than or equal to \(n-1\) and strictly less than \(n\). Hence, the integer part of \(\log\_{10}\) of any \(n\)-digit number will be \(n-1\). So, the number of digits in the number x is given by:

    public static int digits(int x) {
        return (int) Math.log10(x) + 1;
    }

Examples

Returning to the credit card example, suppose that the account number is as follows:

        cardNumber = 412831758;

Then, you can find the number of digits in the account number as follows:

        n = digits(cardNumber);

Now, as you know from Chapter 4, if you want to extract the left-most three digits (i.e., the issuer), you need to drop the rightmost n - 3 digits. This involves dividing by ten to the power of n-3, which you can implement as follows:

        issuer = cardNumber / (int) Math.pow(10.0, n - 3);

As another example, suppose you need to write a program for a newspaper that converts a dollar amount (e.g., a person’s annual income, the price of a house) into a phrase like “6 figures” or “7 figures”. You would again need to calculate the number of digits in the number of interest. So, for example, if you initialize the variable containing the annual income of the subject of the story as follows:

        income = 156720;

you can then figure out the number of “figures” in that variable as follows:

        figures = digits(income);

Looking Ahead

As with the digit manipulation pattern of Chapter 4, this pattern can be used with other representation schemes (i.e., other bases). All that is needed is to replace \(10\) with the desired base, \(b\).

Fortunately, it is easy to calculate the logarithm in one base given the logarithm in another. That is, assuming you have the ability to calculate \(\log\_{10}(x)\) (e.g., using Math.log10() in Java):

\[\log\_{a}(x) = \frac{\log\_{10}(x)}{\log\_{10}(a)}\]

whenever \(x \> 0\).

A Warning

Notice that the truncation pattern from Chapter 6 is not used in this pattern. Instead, typecasting is used to get the integer part of the value returned by Math.log10(). This is because Math.log10() returns a double, and the truncation pattern is for truncating integers.


Licenses and Attributions


Speak Your Mind